完全防止活动转换干扰共享元素转换:
在退出活动中,调用getWindow()。setExitTransition(null);
在进入活动时,调用getWindow()。setEnterTransition(null);
从https://stackoverflow.com/a/34907685/967131
我怀疑这可能有副作用,但不确定。它简直是简单而有效。
防止特定元素闪烁:
我从亚历克斯·洛克伍德的答案开始并做了相当多的尝试以使其正常工作。它的核心是正确的,尽管我不需要他为接收活动所建议的代码,但是我遇到了一些问题,方法是在Fragment(而不是Activity)中调用它,并将工具栏设置为动作栏。
哦,碎片的东西?我看到很多评论,试图检索对状态栏和导航栏的引用为空。同样的事情也发生在我身上,直到我意识到我不会在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相匹配即可。
这样可以防止状态栏,工具栏和导航栏(“后退” /“主页” /“最近使用的应用程序”按钮)在过渡期间闪烁。活动过渡的其余部分是正常的。
就我而言,我们的应用主题android:windowBackground
为蓝色。这会导致过渡中出现蓝色闪烁,这非常令人沮丧。但是,我现在没有选择会影响整个应用程序的更改,而是使用第一个快速而肮脏的选项。