Shared Element Transition Not Working Between Parent And Child Fragments (nested Fragments)
Solution 1:
I am trying to implement Shared Element Transition between my two fragments (parent & child) but it's not happening.
Nothing is happening or at least it looks like nothing is happening because you're using only <changeTransform/> and <changeBounds /> in your default_transition.xml. If bounds of both Fragmentscoincide, there's nothing to "transit".
However, if you add additional animation elements to the file then the transition is actually visible (even if bounds coincide).
Introduction
I have created a sample project similar to yours - BottomNavigationView with a NavHostFragment containing 2 parent Fragments - DashboardFragment and HomeFragment.
Initially, DashboardFragment loads DashboardListFragment that consists of a simple RecyclerView. If any RecyclerView item is clicked then DashboardFragment loads DashboardDetailFragment (bounds in DashboardDetailFragment and DashboardListFragment coincide).
Transition Behaviour
Then, I pretty much reused your showFragmentWithTransition(...) and tried to click each element in the list to check if any transition would be visible - it wasn't.
Hence, I modified the file by adding a simple <slide/> element as below:
<?xml version="1.0" encoding="utf-8"?><transitionSet><slide/><changeTransform /><changeBounds /></transitionSet>And the sliding transition was right there.
I also tried other elements like <fade/> or <explode/> or others - all of them worked just fine too.
Conclusion
Even if a transition is not visible, it doesn't mean it's not happening. You should try other animation elements to see it work.
UPDATE
Since you provided a link to your github code, I peeked into it and brought it to the working condition. I'll leave it up to you to improve it further.
So, basically, your HomeFragment layout file contained both RecyclerView and a placeholder for your child Fragment at the same time. Instead, I split your HomeFragment into 2 entities - one for your parent FragmentHomeFragment containing only the placeholder for any child Fragment and HomeFragmentList containing your previous parent logic.
Then, when a picture is selected, HomeFragment replaces your HomeFragmentList with a ChildFragment. And...it works!
This way, you don't need to use your Activity for creating a child Fragment and it's more independent.
Below, I provide the relevant code that had to be modified.
Code
HomeFragment (new parent)
publicclassHomeFragmentextendsFragment {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_home, container, false);
}
@OverridepublicvoidonViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
HomeFragmentListhomeFragmentList=newHomeFragmentList();
FragmentTransactionfragmentTransaction= getChildFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.child_fragment, homeFragmentList, homeFragmentList.getClass().getName());
fragmentTransaction.commit();
}
}
HomeFragmentList (old parent)
publicclassHomeFragmentListextendsFragmentimplementsAdapterListener {
RecyclerView recyclerView;
private ArrayList<String> images = new ArrayList<>();
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_home_list, container, false);
recyclerView = root.findViewById(R.id.recycler_view);
getImages();
LinearLayoutManager manager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
recyclerView = root.findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(manager);
AdapterClass adapter = new AdapterClass(this, images);
recyclerView.setAdapter(adapter);
return root;
}
voidgetImages() {
images.add("https://rukminim1.flixcart.com/image/832/832/book/0/1/9/rich-dad-poor-dad-original-imadat2a4f5vwgzn.jpeg?q=70");
images.add("https://www.seeken.in/wp-content/uploads/2017/06/The-4-Hour-Work-Week.jpeg");
images.add("https://www.seeken.in/wp-content/uploads/2017/06/Managing-Oneself.jpeg");
images.add("https://www.seeken.in/wp-content/uploads/2017/07/How-to-Win-Friends-and-Influence-People.jpeg");
images.add("https://www.seeken.in/wp-content/uploads/2017/07/THINK-LIKE-DA-VINCI-7-Easy-Steps-to-Boosting-your-Everyday-Genius.jpeg");
images.add("https://www.seeken.in/wp-content/uploads/2017/07/How-To-Stop-Worrying-And-Start-Living.jpg");
images.add("https://www.seeken.in/wp-content/uploads/2017/08/THE-INTELLIGENT-INVESTOR.jpeg");
images.add("https://www.seeken.in/wp-content/uploads/2017/08/Awaken-the-Giant-within-How-to-Take-Immediate-Control-of-Your-Mental-Emotional-Physical-and-Financial-Life.jpg");
images.add("https://www.seeken.in/wp-content/uploads/2017/08/E-MYTH-REVISITED.jpeg");
images.add("https://images-na.ssl-images-amazon.com/images/I/41axGE4CehL._SX353_BO1,204,203,200_.jpg");
images.add("https://rukminim1.flixcart.com/image/832/832/book/0/1/9/rich-dad-poor-dad-original-imadat2a4f5vwgzn.jpeg?q=70");
}
@Override
publicvoiditemClicked(int pos, ModelClass object, View view, String transition) {
MainActivity activity = (MainActivity) getActivity();
ChildFragment myFragment = new ChildFragment();
Bundle bundle = new Bundle();
bundle.putString("IMAGE_URL", object.getItem(pos));
bundle.putInt("POSITION", pos);
bundle.putString("TRANSITION_NAME", transition);
myFragment.setArguments(bundle);
Log.i("HOME FRAGMENT-DEBUG", transition + "/" + view.getTransitionName());
showFragmentWithTransition(getParentFragment(), myFragment, ChildFragment.class.getName(), view, transition);
}
publicvoidshowFragmentWithTransition(Fragment current, Fragment _new, String tag, View sharedView, String sharedElementName) {
FragmentManager manager = current.getChildFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
if (sharedView != null && sharedElementName != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
current.setSharedElementReturnTransition(TransitionInflater.from(getContext()).inflateTransition(R.transition.default_transition));
current.setExitTransition(TransitionInflater.from(getContext()).inflateTransition(android.R.transition.no_transition));
_new.setSharedElementEnterTransition(TransitionInflater.from(getContext()).inflateTransition(R.transition.default_transition));
_new.setEnterTransition(TransitionInflater.from(getContext()).inflateTransition(android.R.transition.no_transition));
transaction.addSharedElement(sharedView, sharedElementName);
Log.i("ACTIVITY-DEBUG", sharedElementName + "/" + sharedView.getTransitionName());
}
}
transaction.replace(R.id.child_fragment, _new, tag);
transaction.addToBackStack(tag);
transaction.commit();
}
}
fragment_home.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><FrameLayoutandroid:id="@+id/child_fragment"android:layout_width="match_parent"android:layout_height="match_parent"/></LinearLayout>fragment_home_list.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"><androidx.coordinatorlayout.widget.CoordinatorLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:background="#FFF"><androidx.core.widget.NestedScrollViewandroid:id="@+id/home_container"android:layout_width="match_parent"android:layout_height="match_parent"app:layout_behavior="@string/appbar_scrolling_view_behavior"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="15dp"android:layout_marginLeft="9dp"android:layout_marginRight="9dp"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recycler_view"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="5dp"android:orientation="vertical"></androidx.recyclerview.widget.RecyclerView></RelativeLayout></androidx.core.widget.NestedScrollView><com.google.android.material.appbar.AppBarLayoutandroid:id="@+id/appbar"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#FFF"><androidx.appcompat.widget.Toolbarandroid:id="@+id/z_toolbar"android:layout_width="match_parent"android:layout_height="wrap_content"android:elevation="4dp"><RelativeLayoutandroid:id="@+id/header_container"android:layout_width="match_parent"android:layout_height="56dp"><ImageViewandroid:id="@+id/logo"android:layout_width="30dp"android:layout_height="30dp"android:layout_marginRight="10dp"android:layout_centerVertical="true"android:layout_alignParentLeft="true"android:src="@mipmap/ic_launcher_round"android:contentDescription="@string/app_name" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerVertical="true"android:layout_toRightOf="@+id/logo"android:textColor="#000"android:textSize="16sp"android:text="Home" /></RelativeLayout></androidx.appcompat.widget.Toolbar></com.google.android.material.appbar.AppBarLayout></androidx.coordinatorlayout.widget.CoordinatorLayout></RelativeLayout>Remark
Please note that the transition for <changeTransform/> and <changeBounds /> is visible because bounds of a selected View in HomeFragmentList are different from that in the child Fragment.
Solution 2:
Shared element transition does not work properly with FragmentTransaction.add method because parent fragment is still alive and resumed. Try
transaction.replace(R.id.child_fragment, newFragment, tag);
Check this discussion thread for more information.
Solution 3:
I'm not sure about the rest of your setup, but for Shared Element Transitions to work correctly, you need to add setReorderingAllowed(true) to your Fragment Transaction like this:
FragmentTransactiontransaction= manager.beginTransaction();
transaction.add(R.id.child_fragment, newFragment, tag);
transaction.addToBackStack(tag);
transaction.addSharedElement(sharedView, sharedElementName);
transaction.setReorderingAllowed(true); // Add this
transaction.commit();
Post a Comment for "Shared Element Transition Not Working Between Parent And Child Fragments (nested Fragments)"