Now (27.0.0 support library) fragment can use support library versions of Transition for fragment transitions, including shared-element transitions.
https://developer.android.com/topic/libraries/support-library/revisions.html#27-0-0
Support android.transition classes provide transition API back to android API level 14.
https://developer.android.com/reference/android/support/transition/package-summary.html
Inspired by: Fragment Tricks (Google I/O ’17).
So let’s start with the build.gradle (support library 27.0.0+) :
implementation 'com.android.support:appcompat-v7:27.0.1' implementation 'com.android.support:design:27.0.1' implementation 'com.android.support.constraint:constraint-layout:1.0.2'
MainActivity XML:
... <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="match_parent" /> ...
MainActivity code:
public class MainActivity extends AppCompatActivity implements MainFragment.MainFragmentInteraction { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setToolBarAndNavigation(); // Unrelated to our example if (savedInstanceState == null) { getSupportFragmentManager() .beginTransaction() .add(R.id.fragment_container, new MainFragment()).commit(); } } //MainFragment.MainFragmentInteraction interface @Override public void onBtnClick(ImageView imageView) { FragmentManager fragmentManager = getSupportFragmentManager(); MainFragment mainFragment = (MainFragment) fragmentManager .findFragmentById(R.id.fragment_container); mainFragment.setExitTransition(new Fade().setDuration(200)); ArticleFragment articleFragment = new ArticleFragment(); articleFragment.setSharedElementEnterTransition( new MyTransition().setDuration(700).setStartDelay(0)); articleFragment.setSharedElementReturnTransition( new MyTransition().setDuration(400).setStartDelay(200)); articleFragment.setEnterTransition(new Fade().setDuration(500)); articleFragment.setEnterTransition(new Fade().setDuration(500)); articleFragment.setExitTransition(new Fade().setDuration(100)); fragmentManager.beginTransaction() .addSharedElement(imageView, ViewCompat.getTransitionName(imageView)) .replace(R.id.fragment_container, articleFragment) .addToBackStack("TAG") .setReorderingAllowed(true) // Need for transition element .commit(); } }
MainFragment XML:
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/imageViewA" android:layout_width="100dp" android:layout_height="100dp" android:layout_marginTop="70dp" android:contentDescription="desc" android:transitionName="@string/image_transition_name" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@mipmap/ic_launcher"/> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"/> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:layout_marginEnd="8dp" android:layout_marginStart="8dp" android:text="Main Fragment" app:layout_constraintBottom_toTopOf="@+id/button" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"/> </android.support.constraint.ConstraintLayout>
MainFragment code:
public class MainFragment extends Fragment { private MainFragmentInteraction mListener; private ImageView mImageView; @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_main, container, false); mImageView = rootView.findViewById(R.id.imageViewA); rootView.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mListener.onBtnClick(mImageView); } }); return rootView; } @Override public void onAttach(Context context) { super.onAttach(context); if (context instanceof MainFragmentInteraction) { mListener = (MainFragmentInteraction) context; } else { throw new ClassCastException(context.toString() + " must implement MainFragmentInteraction"); } } @Override public void onDetach() { super.onDetach(); mListener = null; } public interface MainFragmentInteraction { void onBtnClick(ImageView view); } }
ArticleFragment XML
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/imageViewB" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginBottom="150dp" android:layout_marginEnd="8dp" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:transitionName="@string/image_transition_name" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@mipmap/ic_launcher"/> </android.support.constraint.ConstraintLayout>
ArticleFragment code:
public class ArticleFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_article, container, false); } }
strings.xml
<string name="image_transition_name">image_transition</string>
Mamert Stankiewicz (@mamert_k1)
September 17, 2018What is MyTransition?
rufjvmbn
September 22, 2018MyTransition extends Transition class.
https://developer.android.com/reference/android/app/Fragment.html#setSharedElementEnterTransition(android.transition.Transition)