Shared elements overflow navigation bar in transition animation
Asked Answered
C

3

8

While activities transit one to other, shared elements, which place over the screen in new activity, overlay navigation bar, as shown on picture shared elements overlay navigation bar

Also you can see this bug in video view overlay navigation bar

Clypeate answered 10/9, 2015 at 11:45 Comment(5)
This video is private. :) :PClapboard
I think you know the answer before posting the question.Clapboard
Thank you for your notice. I changed access to the video.Clypeate
@PratikButani my answer is not good enough. I think there is better answer.Clypeate
Can you post your xml?Clapboard
Y
4

(1) Disable the overlay by setting
android:windowSharedElementsUseOverlay="false" in your XML. When disabled, the shared elements will be drawn as part of the called Activity's view hierarchy, making it impossible for the shared elements to accidentally overlap on top of the system UI bars.
Unfortunately, disabling this behavior might end up introducing new problems as well...
For example, you might find that non-shared views in either Activity begin to clip the shared elements as they transition into place. In most cases you can prevent this from happening by setting android:cliptoChildren="false" and "android:clipToPadding="false" for each shared element's parent in your XML, although additional configuration might be required depending on the specific use case.
(2) Add the Action Bar, Status Bar background, and Navigation Bar background as additional shared elements
By making the system bars shared elements, you can ensure that both the original shared elements and the system UI are drawn at the same level on top of the rest of the window's View hierarchy. To obtain a reference to these views, you can use the following code:

View decor = getWindow().getDecorView();
View statusBar = decor.findViewById(android.R.id.statusBarBackground);
View navBar = decor.findViewById(android.R.id.navigationBarBackground);
View actionBar = decor.findViewById(getResources().getIdentifier("action_bar_container", "id", "android"));

You can refer this for more discussion this post

Yuonneyup answered 14/1, 2016 at 8:21 Comment(0)
C
1

I found, it is Android's bug, when you use

<item name="android:windowDrawsSystemBarBackgrounds">true</item>

in activity's theme.

But it needs to set color to status bar, so I could not set it to false. Otherwise it is possible to set this flag in runtime via

if (Build.VERSION.SDK_INT >= 21) {
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
}

Also you can clear this flag via Window's clearFlags method.

Then I clear this flag before start transition animation in second activity and add this flag after transition finished. It needs to do only in called activity.

UPDATE

I found better solution. In Android every shared element views draw on top of decor view. Navigation bar background usually lay on top of decor view. But in transition time shared elements lay higher.

It is possible navigationBarBackground view adds to share elements, which is accessible from getWindow().getDecorView().findViewById(android.R.id.navigationBarBackground). For this you need add it to shared elements in calling activity and add it to shared elements in called activity.

There is one problem. You need wait when navigation background view will be attached to decor view. This is example how solve this problem in onCreate() method in called activity

ActivityCompat.postponeEnterTransition(this);
final View decorView = getWindow().getDecorView();
decorView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
    @Override
    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
        decorView.removeOnLayoutChangeListener(this);
        View navigationBarBackground = getWindow().getDecorView().findViewById(android.R.id.navigationBarBackground);
        if (navigationBarBackground != null) {
            android.support.v4.view.ViewCompat.setTransitionName(navigationBarBackground, "navigationBg");
        }
        ActivityCompat.startPostponedEnterTransition(MyActivity.this);
    }
});
Clypeate answered 10/9, 2015 at 11:45 Comment(4)
You should use Window.STATUS_BAR_BACKGROUND_TRANSITION_NAME and Window.NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME as transition names while using custom backgrounds.Selenium
Finally! Your updated answer worked for me! However, you don't even need to use setTransitionName if you use Window.NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME as transitionName. In fact, calling ActivityCompat.startPostponedEnterTransition(MyActivity.this); in onLayoutChange is enough.Boyd
@Boyd Are you tested it on all versions of Android since API v21?Clypeate
No only tested it on API 25 and 26 so far.Boyd
K
0

If you are using SharedElement transition you can disable the default activity transition which is a fade by calling :

getWindow().setEnterTransition(null);

This will also resolve the problem when the shared element is behind the status bar and a glitch happens when starting the animation.

Karelian answered 1/10, 2015 at 9:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.