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 bothFragments
coincide, 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 aNavHostFragment
containing2
parentFragments
-DashboardFragment
andHomeFragment
.Initially,
DashboardFragment
loadsDashboardListFragment
that consists of a simpleRecyclerView
. If anyRecyclerView
item is clicked thenDashboardFragment
loadsDashboardDetailFragment
(bounds inDashboardDetailFragment
andDashboardListFragment
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: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 bothRecyclerView
and a placeholder for your childFragment
at the same time. Instead, I split yourHomeFragment
into2
entities - one for your parentFragment
HomeFragment
containing only the placeholder for any childFragment
andHomeFragmentList
containing your previous parent logic.Then, when a picture is selected,
HomeFragment
replaces yourHomeFragmentList
with aChildFragment
. And...it works!This way, you don't need to use your
Activity
for creating a childFragment
and 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 selectedView
inHomeFragmentList
are different from that in the childFragment
.