android - 如何在 Activity 场景动画过渡期间防止状态栏和导航栏出现动画?

标签 android android-5.0-lollipop shared-element-transition activity-transition

首先,我的状态栏背景设置为深棕色,我的导航栏背景默认为黑色。我正在使用 Material light 主题。

我正在使用带有默认转换的 ActivityOptions.makeSceneTransitionAnimation 开始一个新 Activity ,我注意到状态栏和导航栏都短暂地褪为白色,然后又恢复为正确的颜色。

根据documentation :

To get the full effect of a transition, you must enable window content transitions on both the calling and called activities. Otherwise, the calling activity will start the exit transition, but then you'll see a window transition (like scale or fade)

我在调用和被调用的 Activity 上都使用 getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

同样,如果我将回车转换更改为幻灯片,状态栏和导航栏都会短暂地具有白色背景的幻灯片转换。

如何防止状态栏和导航栏在 Activity 场景动画过渡期间出现动画?

最佳答案

据我所知,您可以使用两种方法来防止导航/状态栏在过渡期间出现动画:

方法#1:从窗口的默认退出/进入淡入淡出过渡中排除状态栏和导航栏

导航/状态栏在过渡期间淡入淡出的原因是因为默认情况下,所有非共享 View (包括导航/状态栏背景)将分别在您的调用/被调用 Activity 中淡出/淡入一次过渡开始。但是,您可以通过从窗口的默认退出/进入 Fade 转换中排除导航/状态栏背景来轻松解决此问题。只需将以下代码添加到 Activity 的 onCreate() 方法中:

Transition fade = new Fade();
fade.excludeTarget(android.R.id.statusBarBackground, true);
fade.excludeTarget(android.R.id.navigationBarBackground, true);
getWindow().setExitTransition(fade);
getWindow().setEnterTransition(fade);

也可以使用 XML 在 Activity 主题中声明此转换(即在您自己的 res/transition/window_fade.xml 文件中):

<?xml version="1.0" encoding="utf-8"?>
<fade xmlns:android="http://schemas.android.com/apk/res/android">
    <targets>
        <target android:excludeId="@android:id/statusBarBackground"/>
        <target android:excludeId="@android:id/navigationBarBackground"/>
    </targets>
</fade>

方法#2:将状态栏和导航栏添加为共享元素

这种方法建立在 klmprt 的答案之上,几乎对我有用......尽管我仍然需要进行一些修改。

在我调用的Activity中,我使用下面的代码来启动Activity:

View statusBar = findViewById(android.R.id.statusBarBackground);
View navigationBar = findViewById(android.R.id.navigationBarBackground);

List<Pair<View, String>> pairs = new ArrayList<>();
if (statusBar != null) {
  pairs.add(Pair.create(statusBar, Window.STATUS_BAR_BACKGROUND_TRANSITION_NAME));
}
if (navigationBar != null) {
  pairs.add(Pair.create(navigationBar, Window.NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME));
}
pairs.add(Pair.create(mSharedElement, mSharedElement.getTransitionName()));

Bundle options = ActivityOptions.makeSceneTransitionAnimation(activity, 
        pairs.toArray(new Pair[pairs.size()])).toBundle();
startActivity(new Intent(context, NextActivity.class), options);

到目前为止,这与 klmprt 在他的回答中建议的基本相同。但是,我还需要在我调用的 Activity 的 onCreate() 方法中添加以下代码,以防止状态栏和导航栏在过渡期间“闪烁”:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_next);

    // Postpone the transition until the window's decor view has
    // finished its layout.
    postponeEnterTransition();

    final View decor = getWindow().getDecorView();
    decor.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
        @Override
        public boolean onPreDraw() {
            decor.getViewTreeObserver().removeOnPreDrawListener(this);
            startPostponedEnterTransition();
            return true;
        }
    });
}

将状态栏和导航栏背景添加为共享元素将强制将它们绘制在窗口的默认退出/进入淡入淡出过渡之上,这意味着它们在过渡期间不会淡出。更多关于这种方法的讨论可以在 this Google+ post 中找到。 .

关于android - 如何在 Activity 场景动画过渡期间防止状态栏和导航栏出现动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26600263/

相关文章:

ssl - 如何在 Spring-boot 上启用 TLS 1.2?

android - 解析 XML 时出错 : unbound prefix with Toolbar sdk 21

android - 如何使用共享元素转换来缩放 TextView ?

javascript - phonegap db 查询插入/选择语法

android - 如何获取捕获的图像文件路径并保存到数据库?

android - 无法生成未分配的apk文件

android - 从设置 Activity 更改整个 Android 应用程序 Activity 的语言

android - 如何动画状态栏和工具栏的颜色变化(就像新的日历应用程序一样)

android - Activity 和共享 View 之间的动画 : glitchy/hack at the ends of animation?

android - 共享元素过渡到包含 ViewPager 的 fragment