In the Main Activity, I have BottomNavigationView where there are 3 different parent fragments. The parent fragment has recyclerview and on item click of recyclerview, I am launching child fragment for more details about the item. I am trying to implement Shared Element Transition between my two fragments (parent & child) but it's not happening.
There is no issue with launching child fragment also I have checked the transition name and it's the same in child fragment which I assign to an item in the adapter. I am using Random class to assign transition name to item as in single parent fragment I have many recyclerviews. Here is my code:
Adapter
final String transition;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
transition = "transition" + new Random().nextInt(9999999);
viewHolder.image.setTransitionName(transition);
}
viewHolder.container.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mCallback.itemClicked(i, book, viewHolder.image, transition);
}
});
Parent Fragment
@Override
public void itemClicked(int pos, Book book, View view, String transition) {
MainActivity activity = (MainActivity) getActivity();
ChildFragment myFragment = new ChildFragment();
Bundle bundle = new Bundle();
bundle.putString(IntentExtraKeys.TRANSITION_NAME, transition);
myFragment.setArguments(bundle);
activity.showFragmentWithTransition(this, myFragment, ChildFragment.class.getName(), view, transition);
}
Activity
public void showFragmentWithTransition(Fragment current, Fragment newFragment, String tag, View sharedView, String sharedElementName) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
current.setSharedElementReturnTransition(TransitionInflater.from(this).inflateTransition(R.transition.default_transition));
current.setExitTransition(TransitionInflater.from(this).inflateTransition(android.R.transition.no_transition));
newFragment.setSharedElementEnterTransition(TransitionInflater.from(this).inflateTransition(R.transition.default_transition));
newFragment.setEnterTransition(TransitionInflater.from(this).inflateTransition(android.R.transition.no_transition));
}
FragmentManager manager = current.getChildFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.child_fragment, newFragment, tag);
transaction.addToBackStack(tag);
transaction.addSharedElement(sharedView, sharedElementName);
transaction.commit();
}
default_transition
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<changeTransform />
<changeBounds />
</transitionSet>
Child Fragment
Bundle b = getArguments();
if (b != null) {
String transitionName = b.getString(IntentExtraKeys.TRANSITION_NAME);
Logger.info("opening bundle book fragment:" + transitionName);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
image.setTransitionName(transitionName);
}
}
Here is the sample project of issue: https://gitlab.com/iskfaisal/transition-issue
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 bothFragmentscoincide, 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 -
BottomNavigationViewwith aNavHostFragmentcontaining2parentFragments-DashboardFragmentandHomeFragment.Initially,
DashboardFragmentloadsDashboardListFragmentthat consists of a simpleRecyclerView. If anyRecyclerViewitem is clicked thenDashboardFragmentloadsDashboardDetailFragment(bounds inDashboardDetailFragmentandDashboardListFragmentcoincide).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: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
HomeFragmentlayout file contained bothRecyclerViewand a placeholder for your childFragmentat the same time. Instead, I split yourHomeFragmentinto2entities - one for your parentFragmentHomeFragmentcontaining only the placeholder for any childFragmentandHomeFragmentListcontaining your previous parent logic.Then, when a picture is selected,
HomeFragmentreplaces yourHomeFragmentListwith aChildFragment. And...it works!This way, you don't need to use your
Activityfor creating a childFragmentand it's more independent.Below, I provide the relevant code that had to be modified.
Code
HomeFragment (new parent)
HomeFragmentList (old parent)
fragment_home.xml
fragment_home_list.xml
Remark
Please note that the transition for
<changeTransform/>and<changeBounds />is visible because bounds of a selectedViewinHomeFragmentListare different from that in the childFragment.