TL;DR Why this transition does not start from the expected place?
That is, the place where is the CardView.
Platform/Deps: Android Studio 1.0-RC2, TargetSdk 21, MinSdk 21, AppCompat-21.0.2, CardView-21.0.2, RecyclerView-21.0.2.
Tested On: Genymotion Nexus 5 Lollipop Preview
I have three shared elements:
Source:
<CardView
android:transitionName="cardView">
<ImageView
android:transitionName="imageView">
<TextView
android:transitionName="textView">
Target:
<RelativeLayout
android:transitionName="cardView">
<ImageView
android:transitionName="imageView">
<TextView
android:transitionName="textView">
Note below that the transition names are added programmatically. This is because CardView are holded on a RecyclerView and there are many copies of it. I've tried using the same name (as in the XML instance) but doesn't work neither.
The ReciclerView.Adapter does this:
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
//...
ViewCompat.setTransitionName(viewHolder.mCardView, "cardViewTransition" + position);
ViewCompat.setTransitionName(viewHolder.mImageView, "imageTransition" + position);
ViewCompat.setTransitionName(viewHolder.mTextView, "textTransition" + position);
//...
}
The HomeActivity does this:
@Override
protected void onCreate(Bundle savedInstanceState) {
getWindow().requestFeature(android.view.Window.FEATURE_CONTENT_TRANSITIONS);
getWindow().requestFeature(android.view.Window.FEATURE_ACTIVITY_TRANSITIONS);
// ..
mRecyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(this, new RecyclerItemClickListener.OnItemClickListener() {
@Override public void onItemClick(View view, int position) {
Intent intent = new Intent(selfContext, DetailActivity.class);
View imageView = view.findViewById(R.id.imageView);
TextView textView = (TextView)view.findViewById(R.id.textView);
Bundle extras = new Bundle();
extras.putInt("position", position);
extras.putString("text", textView.getText().toString());
intent.putExtras(extras);
String name = ViewCompat.getTransitionName(view);
ActivityOptionsCompat options =
ActivityOptionsCompat.makeSceneTransitionAnimation(selfContext
,Pair.create(view, ViewCompat.getTransitionName(view))
,Pair.create(imageView, ViewCompat.getTransitionName(imageView))
,Pair.create((View)textView, ViewCompat.getTransitionName(textView))
);
ActivityCompat.startActivity(selfContext, intent, options.toBundle());
}
})
);
///...
}
The DetailActivity does this:
@Override
protected void onCreate(Bundle savedInstanceState) {
getWindow().requestFeature(android.view.Window.FEATURE_CONTENT_TRANSITIONS);
getWindow().requestFeature(android.view.Window.FEATURE_ACTIVITY_TRANSITIONS);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
// ...
Bundle extras = getIntent().getExtras();
int mPositionRef = extras.getInt("position");
View base = findViewById(R.id.detail_layout);
View image = findViewById(R.id.imageView);
TextView text = (TextView) findViewById(R.id.txtLabel);
text.setText(extras.getString("text"));
ViewCompat.setTransitionName(base, "cardViewTransition" + mPositionRef);
ViewCompat.setTransitionName(image, "imageTransition" + mPositionRef);
ViewCompat.setTransitionName(text, "textTransition" + mPositionRef);
}
I've debugged and shared elements have the same names in the source and destination.
Why this transition does not start from the expected place? That is, the place where is the CardView.
Complete sample in GitHub
There is a known bug in Lollipop related to nested shared elements (i.e. adding both a view group and one of its children as shared elements at the same time), so it might be related to that (source: Glitch when animating nested views in a shared element Activity transition?).
Try only adding the ImageView and TextView as shared elements instead (not the parent relative layout container).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With