Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing fragments have wrong elevation value

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?

like image 342
zafrani Avatar asked Oct 31 '17 00:10

zafrani


1 Answers

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+.

like image 78
Dimezis Avatar answered Oct 22 '22 20:10

Dimezis