Есть два известных мне подхода для предотвращения анимации панели навигации / состояния во время перехода:
Подход №1: исключить строку состояния и панель навигации из перехода по умолчанию для выхода / входа в окно.
Причина, по которой панель навигации / состояния исчезает и исчезает во время перехода, заключается в том, что по умолчанию все необщие представления (включая фоны панели навигации / строки состояния) будут исчезать / появляться в ваших вызывающих / вызываемых действиях соответственно после начала перехода , Однако вы можете легко обойти это, исключив фон панели навигации / строки состояния из Fade
перехода по умолчанию для выхода / входа в окне . Просто добавьте следующий код в 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 (т.е. в вашем собственном 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 предложил в своем ответе. Однако мне также нужно было добавить следующий код в onCreate()
метод, который я называю Activity, чтобы предотвратить "мигание" строки состояния и панели навигации во время перехода:
@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;
}
});
}
Добавление фона строки состояния и панели навигации в качестве общих элементов приведет к тому, что они будут отображаться поверх переходного перехода выхода / входа по умолчанию для окна, что означает, что они не будут исчезать во время перехода. Более подробное обсуждение этого подхода можно найти в этой публикации в Google+ .
Полностью предотвратите вмешательство переходов Activity в переходы общих элементов:
С https://stackoverflow.com/a/34907685/967131
Я подозреваю, что это может иметь побочные эффекты, но не знаю наверняка. Это очень просто и работает.
Предотвратить мигание определенных элементов:
Я начал с ответа Алекса Локвуда и немного поэкспериментировал, чтобы попытаться заставить его работать. Ядро этого правильное, хотя мне не нужен код, который он предлагает для принимающего Activity, но я столкнулся с некоторыми проблемами, вызвав его во фрагменте (вместо Activity) и установив панель инструментов в качестве панели действий.
О, штука с фрагментами? Я видел много комментариев, что попытки получить ссылки на строку состояния и панель навигации были пустыми. То же самое происходило и со мной, пока я не понял, что не найду их в макете фрагмента ... они были выше этого уровня. Следовательно, приведенный ниже код позволяет получить представление декора из Activity и выполнить поиск. Тогда я нашел их без проблем.
В итоге я разработал этот служебный метод:
Обратите внимание на R.string.transition_appbarlayout и R.id.appbarlayout . Эти идентификаторы являются произвольными, если они соответствуют тому, что использует ваш код. В моем XML я размещаю настраиваемую панель действий следующим образом (отредактировано до самого необходимого):
Если вы не используете такую панель инструментов, эту часть можно удалить из служебного метода.
Затем вы бы назвали его в своем фрагменте так:
Использование любых значений, которые вы хотите, если они соответствуют вашему XML.
Это предотвращает мигание строки состояния, панели инструментов и панели навигации (кнопки назад / домой / последние приложения) во время перехода. В остальном переход Активности нормальный.
В моем случае тема нашего приложения имеет
android:windowBackground
синий цвет. Это вызывает синюю вспышку при переходе, что довольно неприятно. Но вместо того, чтобы вносить изменения, которые влияют на все приложение, как это, сейчас я выберу первый, быстрый и грязный вариант.источник
Вам нужно поделиться ими в
ActivityOptions.makeSceneTransitionAnimation.
Например:
(извините за псевдо, у меня нет точного значения android.R.id под рукой)
Вы можете запустить соответствующий переход после того, как поделитесь взглядами.
источник
Насколько я понимаю, это вызвано перекрытием переходов активности. Чтобы решить эту проблему, я использовал следующие значения в
onCreate()
методах обоих действий:источник
У меня была такая же проблема, и в ответах, похоже, отсутствует важный элемент головоломки. Помните, что при переходе общего элемента все происходит в целевом действии .
Чтобы убрать эффект мигания, просто добавьте к вызываемому действию следующее:
Это должно решить вашу проблему!
источник
getWindow().setEnterTransition(null);
на переходе Entering удалил белый оверлей для меня.источник
Вот как я это сделал. Я разделяю как the, так
Status Bar
иNavigation Bar
inSharedElementTransition
вместе сImageView
:источник