I'm trying to use a shared element animation between 2 fragments, BlankFragment and BlankFragment2. BlankFragment has a recycler view and BlankFragment2 is a details screen. They share an image and I'm using the new navigation component.
In BlankFragment I'm building FragmentNavigator.Extras
and passing the extras to my call to navigate
with the transition name of the shared image (as its a recycler view and these need to be unique),
In BlankFragment2 I'm receiving this name setting it to my image and setting the setSharedElementEnterTransition
The result is that the enter animation works fine but the exit/return doesn't, I've tried setting them and not setting them (because I believe the navigation component should handle this for me) can anyone help?
MainActivity Navigation Setup
private void setNavigation() {
navController = Navigation.findNavController(this, R.id.main_fragment);
NavigationUI.setupActionBarWithNavController(this, navController);
}
Handling back button
@Override
public boolean onSupportNavigateUp() {
return Navigation.findNavController(this, R.id.main_fragment).navigateUp()
|| super.onSupportNavigateUp();
}
BlankFragment OnClick
@Override
public void onClick(View view, int position) {
NavController navController = Navigation.findNavController(recyclerView);
FragmentNavigator.Extras extras = new FragmentNavigator.Extras.Builder().addSharedElement(view, view.getTransitionName()).build();
BlankFragmentDirections.ActionBlankFragmentToBlankFragment2 directions = BlankFragmentDirections.actionBlankFragmentToBlankFragment2(view.getTransitionName());
navController.navigate(directions,extras);
}
BlankFragment2 onCreate with return/exit transition
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setSharedElementReturnTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.move));
setExitTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.no_transition));
setSharedElementEnterTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.move));
getFragmentArguments();
}
Get Arguments Method
private void getFragmentArguments(){
if (getArguments() != null){
transitionName = BlankFragment2Args.fromBundle(getArguments()).getTransitionName();
Log.d(TAG, "transition name " + transitionName);
}
}
Set image transition name
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
image = view.findViewById(R.id.image);
image.setTransitionName(transitionName);
text = view.findViewById(R.id.text);
}
Java
To Fix on return transition, use viewTreeObserver.addOnPreDrawListener
In BlankFragment (fragment with recycle view)
We need to call postponeEnterTransition();
so the transition
will be pospone
Setup addOnPreDrawListener on recycleView as following
RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
//setup for recycle view adapter
ViewTreeObserver viewTreeObserver = recyclerView.getViewTreeObserver();
viewTreeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
startPostponedEnterTransition();
return true;
}
});
That's it.
Follow this link to get more info on ViewTreeObserver follow this link
FIN !!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With