Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transition of nested shared elements does not starts from the expected place

TL;DR Why this transition does not start from the expected place?

That is, the place where is the CardView.

enter image description here

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

The Code (Simplified)

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.

The Question (Again)

Why this transition does not start from the expected place? That is, the place where is the CardView.

Complete sample in GitHub

like image 904
rnrneverdies Avatar asked Oct 31 '22 13:10

rnrneverdies


1 Answers

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).

like image 142
Alex Lockwood Avatar answered Nov 15 '22 05:11

Alex Lockwood