共享元素溢出导航栏中的过渡动画

Ser*_*nko 7 android android-transitions

当活动将一个转移到另一个共享元素时,它们会在新活动的屏幕上显示,覆盖导航栏,如图所示 共享元素覆盖导航栏

您还可以在视频视图叠加导航栏中看到此错误

Ser*_*nko 1

我发现,这是Android的bug,当你使用

<item name="android:windowDrawsSystemBarBackgrounds">true</item>
Run Code Online (Sandbox Code Playgroud)

在活动主题中。

但它需要设置状态栏的颜色,所以我无法将其设置为 false。否则,可以通过以下方式在运行时设置此标志

if (Build.VERSION.SDK_INT >= 21) {
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
}
Run Code Online (Sandbox Code Playgroud)

您也可以通过WindowclearFlags方法清除此标志。

然后,我在第二个活动中开始过渡动画之前清除此标志,并在过渡完成后添加此标志。它只需要在被调用的活动中执行。

更新

我找到了更好的解决方案。在 Android 中,每个共享元素视图都绘制在装饰视图之上。导航栏背景通常位于装饰视图的顶部。但在过渡时期,共享元素的地位更高。

视图可以navigationBarBackground添加到共享元素,可以从 访问getWindow().getDecorView().findViewById(android.R.id.navigationBarBackground)。为此,您需要将其添加到调用活动中的共享元素,并将其添加到被调用活动中的共享元素。

有一个问题。当导航背景视图将附加到装饰视图时,您需要等待。这是如何onCreate()在被调用活动的方法中解决此问题的示例

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);
    }
});
Run Code Online (Sandbox Code Playgroud)

  • 使用自定义背景时,您应该使用“Window.STATUS_BAR_BACKGROUND_TRANSITION_NAME”和“Window.NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME”作为过渡名称。 (2认同)