Фрагмент перехода и альфа-выпуск

Я использую FragmentTransition вместе с SharedElementTransition между 2 Fragments.

Фактический переход элемента и переход Fragment состоят из набора различных переходов для создания желаемой анимации. У меня нет проблем с анимацией, но для ясности я включил все используемые переходы:

    val moveElementTransition: Transition  by lazy { TransitionInflater.from(context).inflateTransition(android.R.transition.move) }
    val noElementTransition:Transition by lazy { TransitionSet().addTransition(TransitionInflater.from(context).inflateTransition(android.R.transition.no_transition)) }
    val exitTransition: Transition by lazy { TransitionSet().addTransition(TransitionInflater.from(context).inflateTransition(android.R.transition.slide_left)).setDuration(200L).setStartDelay(0L) }
    val reenterTransition: Transition by lazy { TransitionSet().addTransition(TransitionInflater.from(context).inflateTransition(android.R.transition.slide_left)).setDuration(200L).setStartDelay(450L) }
    val enterTransition: Transition by lazy { TransitionSet().addTransition(TransitionInflater.from(context).inflateTransition(android.R.transition.slide_bottom)).setDuration(200L).setStartDelay(400L) }

Проблема

Просто чтобы уточнить, все переходы «работают» при переходе от FragmentA к FragmentB и когда я выдвигаю задний стек и реверсирую анимацию.

Однако похоже, что все настройки альфа-канала в видах (включая CardView углов и View альфа-канала) неверны во время перехода. Результат явно уродлив, пока происходит переход, любая альфа отображается неправильно (скорее умноженный эффект, чем наложение). Похоже, что альфа-канал в представлениях неправильно поддерживается при переходах фрагментов?

Пример альфа-виньетки, которую я использую в некоторых представлениях:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <gradient
        android:angle="0"
        android:endColor="@android:color/transparent"
        android:startColor="@color/colorWindowBackgroundTint"
        android:type="linear"/>
</shape>

Скриншот того, как обычно виньетка выглядит слева, и как она выглядит во время анимации перехода фрагмента:

Слева: правильный внешний вид. Справа: ошибка при переходе фрагмента

Кто-нибудь еще сталкивался с этой проблемой, и если да, то можно ли их исправить?

ИЗМЕНИТЬ:

По запросу я создал небольшое тестовое приложение, которое воспроизводит это поведение (проверено на эмуляторе API 23/24/25) - ссылка: https://github.com/TreeFrogApps/FragmentTransitionTest


person Mark Keen    schedule 29.10.2017    source источник
comment
Можете ли вы опубликовать простой проект с таким поведением на github?   -  person azizbekian    schedule 01.11.2017
comment
@azizbekian Привет, добавил ссылку на небольшой тестовый проект, демонстрирующий это поведение при извлечении из стопки.   -  person Mark Keen    schedule 02.11.2017
comment
Я проверил проект и до сих пор вижу поведение, соответствующее API. Не могли бы вы сказать, что вы ожидаете, когда вы выполняете переход?   -  person azizbekian    schedule 02.11.2017
comment
@azizbekian Переход работает с точки зрения анимации, однако при извлечении обратного стека (нажатие назад из фрагмента B) виньетка / вид (слева и справа на экране) сразу исчезает, а прозрачность другого сразу меняется.   -  person Mark Keen    schedule 02.11.2017


Ответы (1)


Я вижу две проблемы с примером приложения, которое вы представили, когда нажата кнопка «Назад» на фрагменте B. Первая заключается в том, что градиент справа, а не изящно скользит вниз, просто исчезает. Вторая проблема заключается в том, что градиент слева изменяется довольно странным образом перед тем, как скатиться вниз. Вот что я вижу в примере приложения:

введите здесь описание изображения

Я не могу сказать, почему мы это видим, но я могу рассказать вам, как это исправить. Относится ли это к вашему реальному приложению или нет, вам придется определить.

Во-первых, давайте исправим странное поведение левой виньетки. Эта проблема каким-то образом связана с переходом от сплошного цвета к прозрачному цвету. Чтобы исправить это, измените конечный цвет на прозрачную версию начального цвета. Внешний вид не изменится.

shape_vignette_left.xml

<shape 
    android:shape="rectangle">
    <gradient
        android:angle="0"
        android:startColor="#FF303F9F"
        android:endColor="#00303F9F"
        android:type="linear" />
</shape>

Я использовал цветовые константы вместо идентификаторов только для простоты демонстрации этого.

Теперь давайте исправим правую виньетку. Это (опять же каким-то образом) связано с вращением рисуемой фигуры. Чтобы исправить это, создайте новую фигуру, которую можно рисовать, со встроенным вращением, поменяв местами начальный и конечный цвета фигуры выше и удалив вращение из макета следующим образом:

shape_vignette_right.xml

<shape 
    android:shape="rectangle">
    <gradient
        android:angle="0"
        android:startColor="#00303F9F"
        android:endColor="#FF303F9F"
        android:type="linear" />
</shape>

А вот и новый макет:

fragment_b_layout.xml

<FrameLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <View
        android:layout_width="64dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="@drawable/shape_vignette_left" />

    <View
        android:layout_width="64dp"
        android:layout_height="match_parent"
        android:layout_gravity="right"
        android:background="@drawable/shape_vignette_right" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Fragment B"
        android:textColor="@android:color/white" />

</FrameLayout>

Вот как это выглядит по завершении вышеуказанных изменений:

введите здесь описание изображения

Гораздо приятнее.


В качестве продолжения, вот исходный левый рисунок (полный экран) с начальным/конечным цветом "#FF303F9F" и "@android:color/transparent":

введите здесь описание изображения

Вот тот же рисунок с начальным/конечным цветами «#FF303F9F» и «#00303F9F». Любые представления, расположенные позади рисуемого, будут становиться все более и более заметными по мере перехода цвета от полностью непрозрачного ("#FF303F9F") к полностью прозрачному ("#00303F9F").

введите здесь описание изображения

person Cheticamp    schedule 03.11.2017
comment
К сожалению, эффект прозрачности - это то, что мне нужно, мой оригинальный пост показывает, как изображения проходят под виньеткой, это желаемый эффект, который мне нужен. Если я использую сплошной цвет, это не сработает. Пример приложения должен был показать проблему (было запрошено в комментарии), а не мой вариант использования. - person Mark Keen; 03.11.2017
comment
@MarkKeen Изменения в начальных и конечных цветах, которые я опубликовал, также переходят к прозрачности. Первые две цифры — это альфа: FF — непрозрачный, а 00 — прозрачный. Таким образом, начальный цвет #FF303F9F, переходящий в конечный цвет #00303F9F, переходит от полностью непрозрачного к полностью прозрачному. Я опубликую сравнение бок о бок. - person Cheticamp; 03.11.2017
comment
@MarkKeen См. обновленный ответ для получения обновленной информации о прозрачности. - person Cheticamp; 03.11.2017
comment
Ах... Теперь понятно, извините... Только что проверил в моем реальном приложении... работает нормально. Понятия не имею, почему прозрачный цвет является проблемой в Android! Больше беспокоит то, почему я сам об этом не подумал!! Большое спасибо! - person Mark Keen; 03.11.2017
comment
@MarkKeen Это останется загадкой. - person Cheticamp; 03.11.2017
comment
Наверное, к лучшему так и останется ;) - person Mark Keen; 05.11.2017