完全防止 Activity 过渡干扰共享元素过渡:
在退出活动上,调用 getWindow().setExitTransition(null);
在进入活动时,调用 getWindow().setEnterTransition(null);
来自https://stackoverflow.com/a/34907685/967131
我怀疑这可能有副作用,但不确定。它非常简单并且可以工作。
防止特定元素闪烁:
我从亚历克斯洛克伍德的回答开始,做了一些实验来尝试让它发挥作用。它的核心是正确的,虽然我不需要他为接收活动建议的代码,但我通过在片段(而不是活动)中调用它并将工具栏设置为操作栏遇到了一些问题。
哦,碎片的东西?我看到很多评论试图检索对状态栏和导航栏的引用是空的。同样的事情也发生在我身上,直到我意识到我无法在 Fragment 的布局中找到它们……它们高于那个水平。因此,下面的代码从 Activity 获取装饰视图并进行搜索。然后我发现他们没有问题。
最后,我开发了这个实用方法:
public static Bundle transitionOptions(Activity activity, int transitionViewResId, int transitionNameResId) {
if (VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) {
return null;
}
View decorView = activity.getWindow().getDecorView();
View statusBar = decorView.findViewById(android.R.id.statusBarBackground);
View navigationBar = decorView.findViewById(android.R.id.navigationBarBackground);
View appBarLayout = decorView.findViewById(**R.id.appbarlayout**);
View transitionView = decorView.findViewById(transitionViewResId);
String transitionName = activity.getString(transitionNameResId);
List<Pair<View, String>> pairs = new ArrayList<>();
pairs.add(Pair.create(statusBar, Window.STATUS_BAR_BACKGROUND_TRANSITION_NAME));
pairs.add(Pair.create(navigationBar, Window.NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME));
if (appBarLayout != null) {
pairs.add(Pair.create(appBarLayout, activity.getString(**R.string.transition_appbarlayout**)));
}
pairs.add(Pair.create(transitionView, transitionName));
//noinspection unchecked - we're not worried about the "unchecked" conversion of List<Pair> to Pair[] here
return ActivityOptionsCompat.makeSceneTransitionAnimation(activity, pairs.toArray(new Pair[pairs.size()]))
.toBundle();
}
注意R.string.transition_appbarlayout和R.id.appbarlayout。这些 ID 是任意的,只要它们与您的代码使用的匹配即可。在我的 XML 中,我像这样布置自定义操作栏(编辑到基本要素):
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.AppBarLayout
android:id="**@+id/appbarlayout**"
android:transitionName="**@string/transition_appbarlayout**">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"/>
</android.support.design.widget.AppBarLayout>
如果您不使用这样的工具栏,则可以从实用程序方法中删除该部分。
然后你会像这样在你的 Fragment 中调用它:
startActivity(intent, UIUtils.transitionOptions(getActivity(),
R.id.**my_view**,
R.string.**transition_my_view**));
使用您想要的任何值,只要它与您的 XML 匹配。
这可以防止状态栏、工具栏和导航栏(返回/主页/最近的应用程序按钮)在过渡期间闪烁。Activity 过渡的其余部分是正常的。
在我的例子中,我们的应用程序主题有一个android:windowBackground
蓝色。这会导致过渡中出现蓝色闪烁,这非常令人沮丧。但是,与其做出像那样影响整个应用程序的更改,现在我将使用第一个快速且肮脏的选项。