Replacing fragments have wrong elevation value
Asked Answered
T

1

16

Hello again stack overflowians. I have another fragment question. (I'm using android.app.Fragment not Support Fragments)

I'm trying to replace a fragment. But this isn't as simple as using:

fragmentTransaction
    .replace(containerId, newFragment)
    .addToBackStack("unique tag")
    .commit()

Why not? Good question friends, its because my newFragment has a transition animation.

Where is the animation defined? Another great question, its defined in the fragments onCreateAnimator()

Why is it defined there? A long answer to why can be found: Nested fragments transitioning incorrectly. For now you need to trust that this is how things need to be done in my project.

What is the animation doing? A simple scroll from the edge of the screen into the center of it, completely covering the original fragment. Keep in mind that in this scenario the old fragment is just sitting in place. It has an animation effect to not move.


What is the problem?

The problem is that newFragment seems to have a lower elevation (or z?) value than the old one. So the transition isn't able to be observed because the old fragment is sitting above the new fragment. Upon reaching the end of the animation duration you see the new fragment blink above the old one. I expected the newFragment to cover the old one from the beginning of the animation.


Why not use add? This seems to create more problems, as I have many fragments I want to swap in and out of the view. Using add seems to trigger their exit animations the next time I use replace, even if there are 1...n fragments in front of it. They also don't pause.

Why not set the elevation? Because I'm supporting api 19 which doesn't have an elevation property.

Why not use ViewCompat.setElevation() for api 19? I tried it and have the same failing results.

Has anyone found a way to get around this problem?

Transpontine answered 31/10, 2017 at 0:34 Comment(14)
Have you tried applyin setReorderingAllowed(false) before commiting the transaction?Megmega
@Megmega that is only available on API 26+Transpontine
Not quite true, support fragments are available at least for API 14 onwards.Megmega
Sorry I'm not using the support fragment managerTranspontine
For framework fragments use setAllowOptimization(false).Megmega
I see that in support fragment manager developer.android.com/reference/android/support/v4/app/… but not in the android.app's developer.android.com/reference/android/app/…Transpontine
What is your reasoning for using Fragments over Support Fragments?Wie
I'm not supporting apis before 19.Transpontine
@Zafrani Have you tried setting the elevation for the fragment that's being covered to be lower rather than raising the fragment that's making an entrance?Fetid
@JoeyHarwood Yes but that doesn't work for API 19 when I have to use View.setElevationTranspontine
I'm not sure it's actually possible to get around this issue but an easy way to "fake" it is to fade out the current fragment quickly while the incoming fragment is transitioning in.Easterling
We do something very similar in terms of the 2 fragments and animating. The only difference is we do not animate the fragments but the contents within them. So basically we would animate out the contents of the bottom fragment (while all children of the top fragment is invisible). After the animations of the bottom fragment is complete we then start the top fragment animations and remove the bottom fragment to get seamless transitions within the fragments. Don't know if this could work for you but it's worth a shot.Bracken
Please post a complete example (Github) or at least your onCreateAnimator code and your animation definitions.Idonna
can you post a screenshot of your issue? may be i can help with viewsGull
D
5

I had the same problem, and spent quite a lot of time trying to fix it. Unfortunately, from my experience, there's no way to make it work for API <=19 on this setup.

ViewCompat.setElevation() is simply a NoOp for <=19 API, so it can't work. Starting from SDK 21, it sets an elevation and it kinda fixes the problem. Setting Z index works as well.

The only thing I can advice is to change the transition for API <=19 to not depend on the Z index anyhow. And for 21+ use the transition you wanted. This was the way I did it, and I think it's fine, because the majority of users are on 21+.

Dube answered 12/11, 2017 at 20:30 Comment(1)
I'm afraid that this is the only option I have.Transpontine

© 2022 - 2024 — McMap. All rights reserved.