Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shared elements overflow navigation bar in transition animation

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

like image 561
Sergei Vasilenko Avatar asked Sep 10 '15 11:09

Sergei Vasilenko


2 Answers

(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

like image 121
Canberk Ozcelik Avatar answered Nov 09 '22 01:11

Canberk Ozcelik


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);
    }
});
like image 20
Sergei Vasilenko Avatar answered Nov 09 '22 01:11

Sergei Vasilenko