Fragment enter and exit transitions are not executed at the same time - android

Running a simple slide to the left animation for both entering and existing fragment produces the effect of the entering fragment slightly overlapping with the exit fragment. This leads me to think that both transition are not executed at the same time. Any clue or confirmation of this behavior?
The desired effect is to slide the fragments to the left at the same time, without overlap.
The code:
Fragment current = ...;
Fragment fragment = ...;
Transition slideIn = TransitionInflater.from(this)
.inflateTransition(R.transition.fragment_indicator_enter)
.setDuration(300)
.setInterpolator(new LinearInterpolator());
fragment.setEnterTransition(slideIn);
currentFragment.setExitTransition(TransitionInflater.from(this)
.inflateTransition(R.transition.fragment_indicator_exit)
.setDuration(300)
.setInterpolator(new LinearInterpolator()));
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, fragment)
.addToBackStack(null)
.commit();
The only workaround by know it has been to add a setStartDelay(30) for the entering transition. But weird thing, I have different transitions for different fragments and the startDelay has to be different to produce the effect of both fragment sliding to the left at the same time.

The effect is an expected behavior of the transition, as all the views in the layout are moved at a different time to avoid moving everything as a block a create some natural sense of motion. I intentionally want this block effect, so it's solved by adding a target for the transition, where this target is the FrameLayout containing the views of the fragment.
fragment.setEnterTransition(new Slide(Gravity.RIGHT)
.addTarget(R.id.whole_content));

Did you try placing the animations directly in the transaction call?
getSupportFragmentManager()
.setCustomAnimations(R.transition.fragment_indicator_enter, R.transition.fragment_indicator_exit)
.beginTransaction()
.replace(R.id.fragment_container, fragment)
.addToBackStack(null)
.commit();

Related

FragmentTransaction.TRANSIT_NONE is not working as expected

How can I switch to another fragment without any animation?
I have two fragments and show/hide them using this:
supportFragmentManager
.beginTransaction()
.hide(currentFragment)
.show(selectedFragment)
.setTransition(FragmentTransaction.TRANSIT_NONE)
.commit()
I expect them to switch without any animation, but there is a fade animation.
If I set the transition to TRANSIT_FRAGMENT_FADE, The fade animation will be shorter:
I'm using androidx version 1.6.0-alpha02 and kotlin version 1.4.32
Thank you.
FragmentTransactions sets the animation for a fragment entering or exiting the transaction.
show(): displays a previously hidden fragment. This is only relevant for fragments that have been added to the container. Show will use the FragmentTransaction that was used when the Fragment originally entered the container.
hide(): Hides the existing fragment. This is only relevant for fragments whose views have been added to a container, as this will cause the view to be hidden. Hide will use the FragmentTransaction that was set when the fragment originally entered the trasaction.
In your case when you call FragmentTransaction, it isn't setting the animation because you don't have a fragment entering or exiting the container, you are using hide and show to display your fragment so the FragmentTransaction is using the animation for when the fragments had originally entered the container.
If you wish to control the animation I would suggest using replace instead of show and hide`.
I found the problem.
It was because of Shared Element Transition that was setting in onCreate.
sharedElementEnterTransition = TransitionInflater.from(context).inflateTransition(android.R.transition.move)
Removing this line fixed the problem.
However I wonder in case of having a shared element transition, how can I navigate to another fragment without fading animation...

Make replaced fragment visible while transition ongoing

Im using Navigation Architecture Component and i got my shared element transition between two fragments working fine. First fragment contains recyclerview and second one is a "details" of recyclerview item. The problem is that i need to keep first fragment visible while transition in progress.
How do i make transition like that ? Is there any option to achieve this with Navigation Architecture Component ? If no, what i need to use ?
The way exit transitions work is by adding the target views to a ViewOverlay that is added to the entering fragment. This means that, once the fragment is replaced, only the entering fragment exists and all the transitions applied to views that are exiting are actually happening on views that have been added to the entering fragment's ViewOverlay.
The reason why your exiting fragment doesn't stay visible is because you don't have an exit transition which means that no views are added to the ViewOverlay of the entering fragment.
Each view that is targeted in the exit transition is added to the ViewOverlay which sits on top of the entering fragments view hierarchy. So having the exiting fragment just sit there whilst the transition happens is not possible because once you target any views of the exiting fragment it will cause them to be on top of the view hierarchy, thus hiding all the other views (including the shared element).
Your best bet is probably to use a Fade transition as the exit transition and this way you can create a cross fade between the fragments
I dont know is it really possible with Navigation.
But its really possible with basic FragmentTransaction
fragmentManager!!
.beginTransaction()
.setReorderingAllowed(true) // setAllowOptimization before 26.1.0
.addSharedElement(view.imageIV, "fragment_news_iv")
.addSharedElement(view.title, "fragment_news_title_tv")
.addSharedElement(view.date, "fragment_news_date_tv")
.addSharedElement(view.container, "fragment_news_scrollView")
.addSharedElement(view.description, "fragment_news_description_tv")
.addToBackStack(null)
.setCustomAnimations(
android.R.anim.fade_in,
android.R.anim.fade_out,
android.R.anim.fade_in,
android.R.anim.fade_out
)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.add(
R.id.main_host_fragment,
NewsDetailsFragment(),
NewsDetailsFragment::class.java.simpleName
).addToBackStack(null)
.hide(this#MainFragment)
.commit()
Here is part of code which is doing transaction.
U can set custom animations like fade_in, fade_out with long duration(1000ms)
.setCustomAnimations(
android.R.anim.fade_in,
android.R.anim.fade_out,
android.R.anim.fade_in,
android.R.anim.fade_out
)
And set sharedEnterTransition in detailsFragment with duration 200
val trans = TransitionInflater.from(context).inflateTransition(android.R.transition.move)
trans.apply {
duration = 200
enterTransition = trans
}
sharedElementEnterTransition = trans
So its obvious that first fragment will still be visible while transaction will be in progress. This is kinda workaround solution, but works)

White flash/flicker during shared element transition between fragments

I'm using shared element transition between two fragments. The animation works well, but there is a white flash which happens in the fragment.
In my first fragment, I set shared element transition using:
getActivity().getSupportFragmentManager()
.beginTransaction()
.addSharedElement(ivPic, ViewCompat.getTransitionName(ivPic))
.addToBackStack(null)
.replace(R.id.fragment_container, fragment)
.commit();
And in my second fragment inside onCreate():
Transition transition = TransitionInflater.from(getContext()).inflateTransition(R.transition.shared_element_transition);
setSharedElementEnterTransition(transition);
setSharedElementReturnTransition(transition);
Things I've tried:
setEnterTransition(null) in my second fragment
setCustomAnimations(0, 0) in fragment transition in first fragment

programmatically adding custom animation to fragment using objectAnimator

I currently add custom animation to my fragments using the following code.
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.setCustomAnimations(R.animator.slide_in, R.animator.slide_in, R.animator.slide_out, R.animator.slide_out );
ft.add(R.id.container, new Doze1Fragment());
ft.addToBackStack(null);
ft.commit();
Now I'm playing around with adding a few different fragments on top of each other in a span of 3 to 5 seconds and then pop all of them out of the back stack to get a "fanning" animation out of all fragments. In order to do so I either add a delay in between each popBackStack() call (I think this is a horrible solution), or make a custom XML animator resource for each fragment. I was wondering if anyone has any idea of how to do this programmatically right before calling ft.add(R.id.container, new Doze1Fragment()). I know that normally I could use the following code to animate a view and I was looking for something similar
ObjectAnimator oa = ObjectAnimator.ofFloat(R.id.container, "x", 0, 1000f);
oa.setDuration(300);
oa.start();
Thanks in advance.

Android - Animate fragment entrance after it's drawn?

I'm using the Support Library and replacing a fragment with a custom slide-in animation.
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.setCustomAnimations(enterIn, enterFragmentOut);
transaction.replace(R.id.content_frame, contentFragment);
transaction.commit();
The problem I'm experiencing is that the animation starts concurrently with the drawing of the fragment's views, and since the fragment has a rather complex layout (ListViews, &c) the animation is very stuttery (only a handful of frames are shown).
I've tried splitting the operation into two parts (with transaction1 = {add_new, hide}, transaction2 = {remove_old, show}) and firing the second transaction after onCreateView() has executed on the new fragment, but I didn't get much improvement at all.
What I'm looking for is a way to start the animation after the new fragment is fully drawn, if that's at all possible. Or any other tips that you may have on this issue...
Any ideas? Thanks a lot.

Categories

Resources