Место действия. Слайд-переход под представлениями

Посмотрите на образец. У меня есть две сцены, которые являются начальной и конечной сценами. Макет стартовой сцены:

<?xml version="1.0" encoding="utf-8"?>
<merge
    android:id="@+id/vgRoot"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:parentTag="RelativeLayout"
    tools:ignore="HardcodedText"
    >

    <Button
        android:id="@+id/btn1"
        style="@style/Widget.AppCompat.Button.Borderless"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/cardView"
        android:text="Button"
        android:layout_centerHorizontal="true"
        />

    <Button
        android:id="@+id/btnGo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/btn1"
        android:text="@string/go"
        android:layout_centerHorizontal="true"
        />

    <android.support.v7.widget.CardView
        android:id="@+id/cardView"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:layout_margin="16dp"
        android:translationZ="3dp"
        >

        <FrameLayout
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:background="#3829AB"
            android:padding="32dp"
            >

            <TextView
                android:id="@+id/tvText"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Text Title"
                android:textAppearance="?android:textAppearanceMedium"
                android:textColor="@android:color/white"
                />

        </FrameLayout>

    </android.support.v7.widget.CardView>

</merge>

У меня есть btn1, для которого применяется скользящий переход, cardView и container, которые меняют свои границы, и tvText как тело CardView.

И финальная сцена:

<?xml version="1.0" encoding="utf-8"?>
<merge
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:ignore="HardcodedText"
    tools:parentTag="RelativeLayout"
    >

    <android.support.v7.widget.CardView
        android:id="@+id/cardView"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        app:cardCornerRadius="0dp"
        >

        <FrameLayout
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="8dp"
            android:background="#3829AB"
            android:orientation="vertical"
            >

            <TextView
                android:id="@+id/tvText"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Text Title"
                android:textAppearance="?android:textAppearanceMedium"
                android:textColor="@android:color/white"
                />

        </FrameLayout>

    </android.support.v7.widget.CardView>

</merge>

Код фрагмента с переходом:

public class FragmentStartTransition extends Fragment {
    @BindView(R.id.btnGo) View btnGo;
    @BindView(R.id.vgRoot) ViewGroup vgRoot;

    private Unbinder unbinder;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        ViewGroup view = (ViewGroup) inflater.inflate(R.layout.fragment_start_transition, container, false);
        unbinder = bind(this, view);
        return view;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        btnGo.setOnClickListener(btnGo.setOnClickListener(v -> moveNext());
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        unbinder.unbind();
    }

    private void moveNext() {
        Scene scene = Scene.getSceneForLayout(vgRoot, R.layout.scene_end, getContext());
        TransitionManager.go(scene, getTransition());
    }

    private Transition getTransition() {
        Slide slide = new Slide(Gravity.TOP);
        slide.addTarget(R.id.btn1);

        ChangeBounds changeBounds = new ChangeBounds();
        changeBounds.addTarget(R.id.cardView);
        changeBounds.addTarget(R.id.container);
        changeBounds.addTarget(R.id.tvText);

        return new TransitionSet()
                .setOrdering(TransitionSet.ORDERING_TOGETHER)
                .addTransition(slide)
                .addTransition(changeBounds)
                .setDuration(1500);
    }
}

фрагмент_начало_перехода:

<RelativeLayout
    android:id="@+id/vgRoot"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:ignore="HardcodedText"
    >

    <include layout="@layout/scene_start"/>

</RelativeLayout>

Результат анимации:

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

Я хочу поместить btn1 под cardView и container. Как видите, cardView расположен в конце корневого макета над кнопкой. Но в результате анимация скользит по cardView. Могу ли я как-то контролировать такие отношения оси Z между анимированными представлениями?

пробовал cardView.bringToFront() - не помогает

определенно должно быть простое решение, но я не могу его найти.
Мне нужна ваша помощь, ребята.

Обновление: это связано с тем, что фреймворк рисует переход слайдов в наложении представления контейнера сцены, посмотрите на класс android.transition.Visibility:

 sceneRoot.getOverlay().add(overlayView);

Но вопрос пока открыт.


person Beloo    schedule 25.07.2017    source источник
comment
добавьте это в свою карточку и попробуйте android:elevation=10dp   -  person Anil    schedule 25.07.2017
comment
@Anil Не так просто (это не работает как translationZ манипуляция   -  person Beloo    schedule 25.07.2017
comment
Вы когда-нибудь догадывались об этом. Я испытываю нечто подобное.   -  person kailoon    schedule 31.01.2018
comment
У меня такая же проблема. Поскольку класс android.transition.Visibility добавляет скользящее представление к наложению, как указывает @Beloo, это кажется невозможным без написания собственного подкласса android.transition.Transition. Я могу попытаться это сделать, и если мне это удастся, я поделюсь.   -  person Doug McBride    schedule 10.02.2018


Ответы (1)


Я только что решил ту же проблему. Хитрость заключается в том, чтобы не позволить классу Visibility копировать скользящий (исчезающий) вид в оверлей корня сцены, который, очевидно, будет отображаться поверх любого другого вида в сцене.

Скользящее представление копируется в наложение только в том случае, если оно фактически удалено из иерархии представлений. Если вместо этого я оставлю вид в сцене, но установлю его visibility на GONE, он повторно использует тот же вид, а не копирует его в оверлей. Затем он будет скользить под своими одноуровневыми представлениями, если он находится под ними (так что ваш cardView.bringToFront() должен работать).

person Doug McBride    schedule 11.02.2018