Полностью предотвратите вмешательство переходов Activity в переходы общих элементов:
При завершении действия вызовите getWindow (). SetExitTransition (null);
При входящей активности вызовите getWindow (). SetEnterTransition (null);
С https://stackoverflow.com/a/34907685/967131
Я подозреваю, что это может иметь побочные эффекты, но не знаю наверняка. Это очень просто и работает.
Предотвратить мигание определенных элементов:
Я начал с ответа Алекса Локвуда и немного поэкспериментировал, чтобы попытаться заставить его работать. Ядро этого правильное, хотя мне не нужен код, который он предлагает для принимающего Activity, но я столкнулся с некоторыми проблемами, вызвав его во фрагменте (вместо Activity) и установив панель инструментов в качестве панели действий.
О, штука с фрагментами? Я видел много комментариев, что попытки получить ссылки на строку состояния и панель навигации были пустыми. То же самое происходило и со мной, пока я не понял, что не найду их в макете фрагмента ... они были выше этого уровня. Следовательно, приведенный ниже код позволяет получить представление декора из 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 . Эти идентификаторы являются произвольными, если они соответствуют тому, что использует ваш код. В моем 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>
Если вы не используете такую панель инструментов, эту часть можно удалить из служебного метода.
Затем вы бы назвали его в своем фрагменте так:
startActivity(intent, UIUtils.transitionOptions(getActivity(),
R.id.**my_view**,
R.string.**transition_my_view**));
Использование любых значений, которые вы хотите, если они соответствуют вашему XML.
Это предотвращает мигание строки состояния, панели инструментов и панели навигации (кнопки назад / домой / последние приложения) во время перехода. В остальном переход Активности нормальный.
В моем случае тема нашего приложения имеет android:windowBackground
синий цвет. Это вызывает синюю вспышку при переходе, что довольно неприятно. Но вместо того, чтобы вносить изменения, которые влияют на все приложение, как это, сейчас я выберу первый, быстрый и грязный вариант.