In my application I have a list of items displayed through a RecyclerView
adapter. If I click on an item a new Fragment
in started within the same Activity
. The layout of my item and my Activity look (simplified) like this:
Activity layout:
<android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.AppBarLayout>
<android.support.design.widget.CollapsingToolbarLayout>
<ImageView
android:id="@+id/image"
android:transitionName="image" ... />
<android.support.v7.widget.Toolbar ... />
</android.support.design.widget.CollapsingToolbarLayout>
<android.support.design.widget.TabLayout ... />
</android.support.design.widget.AppBarLayout>
<FrameLayout... />
</android.support.design.widget.CoordinatorLayout>
Item Layout:
<RelativeLayout >
<ImageView
android:id="@id/itemImage"
android:transitionName="image" />
<LinearLayout>
<TextView ... />
<TextView ... />
</LinearLayout>
</RelativeLayout>
Now, if the new fragment is started by an item click, I would like to add an animation of the item image to the ImageView
in the CollapsingToolbarLayout
. I read the article about ShareElement animations but this does not work here because this is not a real ShareElement animation. The target ImageView
is not in the new fragment neither I have to start a new activity (I only make the target ImageView
visible in the new Fragment
). So how would I create such an animation in this case?
So, you are trying to animate a view from one layout to another.
I think this can be achieved using ViewOverlays API. You can see a detailed answer about that API here.
Now in your case, what you'll end up with is you'd add your ImageView
to the ViewGroupOverlay
of the root layout:
final ViewGroup container = (ViewGroup) findViewById(R.id.content);
container.getOverlay().add(imageView);
...
From the docs:
If the view has a parent, the view will be removed from that parent before being added to the overlay.
Thus, as soon as you perform getOverlay().add(imageView)
the view would be removed from it's parent. Now you are free to create your animation and move the imageView
to the final destination.
final ViewGroup container = (ViewGroup) findViewById(R.id.content);
container.getOverlay().add(imageView);
// animate imageView by any API, e.g. ViewPropertyHolder
imageView.animate()
.x(finalX)
.y(finalY)
.setDuration(duration)
.setInterpolator(interpolator)
.withEndAction(() -> {
// crucial point, remove the overlay
container.getOverlay().remove(imageView);
// add this `imageView` to the destination layout
destLayout.addView(imageView);
})
Here's a similar feature you're trying to implement:
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