Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to start shared element transition using Fragments?

I am trying to implement transitions between fragments which have "shared elements" as described in the new material design specs. The only method I can find is the ActivityOptionsCompat.makeSceneTransitionAnimation, which I believe works on Activity only. I've been searching for this same functionality but with/for fragments.

like image 992
unchosen Avatar asked Oct 25 '14 10:10

unchosen


People also ask

Which of the following transitions is a shared elements transition?

Android also supports these shared elements transitions: changeBounds - Animates the changes in layout bounds of target views. changeClipBounds - Animates the changes in clip bounds of target views. changeTransform - Animates the changes in scale and rotation of target views.

How do you animate fragment transitions?

At a high level, here's how to make a fragment transition with shared elements: Assign a unique transition name to each shared element view. Add shared element views and transition names to the FragmentTransaction . Set a shared element transition animation.

How do you animate a fragment?

To animate the transition between fragments, or to animate the process of showing or hiding a fragment you use the Fragment Manager to create a Fragment Transaction . Within each Fragment Transaction you can specify in and out animations that will be used for show and hide respectively (or both when replace is used).

What is shared transition?

Shared Element Transition is one of the most seen animations in Android apps. This type of animation is used when we have to open an item from a ListView or RecyclerView. Shared Element Transition in Android determines how shared element views are animated from activity to activity or fragment to fragment.


2 Answers

I had the same problem but had it working by adding a new fragment from another fragment. The following link is very helpful in getting started on this: https://developer.android.com/training/material/animations.html#Transitions

Following is my code that works. I'm animating an ImageView from one fragment to the other. Make sure the View you want to animate has the same android:transitionName in both fragments. The other content doesn't really matter.

As a test, you could copy this to both your layout xml files. Make sure the image exists.

<ImageView android:transitionName="MyTransition" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:src="@drawable/test_image" /> 

Then I have 1 file in my res/transition folder, named change_image_transform.xml.

<?xml version="1.0" encoding="utf-8"?> <transitionSet xmlns:android="http://schemas.android.com/apk/res/android">     <changeImageTransform /> </transitionSet> 

Now you can get started. Lets say you have Fragment A containing the image and want to add Fragment B.

Run this in Fragment A:

@Override public void onClick(View v) {     switch(v.getId()) {         case R.id.product_detail_image_click_area:             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {                 setSharedElementReturnTransition(TransitionInflater.from(getActivity()).inflateTransition(R.transition.change_image_transform));                 setExitTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.explode));                  // Create new fragment to add (Fragment B)                 Fragment fragment = new ImageFragment();                 fragment.setSharedElementEnterTransition(TransitionInflater.from(getActivity()).inflateTransition(R.transition.change_image_transform));                 fragment.setEnterTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.explode));                  // Our shared element (in Fragment A)                 mProductImage   = (ImageView) mLayout.findViewById(R.id.product_detail_image);                  // Add Fragment B                 FragmentTransaction ft = getFragmentManager().beginTransaction()                         .replace(R.id.container, fragment)                         .addToBackStack("transaction")                         .addSharedElement(mProductImage, "MyTransition");                 ft.commit();             }             else {                 // Code to run on older devices             }             break;     } } 
like image 75
ar34z Avatar answered Sep 18 '22 06:09

ar34z


The shared element fragment transitions do work with ListViews, as long as the source and target views have the same (and unique) transitionName.

If you make your list view adapter to set unique transitionNames to the views you want (e.g. some constant + specific item id) and also change your detail fragment to set the same transitionNames to the target views at runtime (onCreateView), the transitions actually work!

like image 26
Dimitris Kazakos Avatar answered Sep 20 '22 06:09

Dimitris Kazakos