Переходы: Как изменить размер родительского представления после завершения перехода? - PullRequest
0 голосов
/ 07 июля 2019

В моем приложении у меня линейная компоновка просмотров.Размер этих представлений может измениться из-за изменений в их собственном макете.В частности, первое представление (sceneRoot) состоит из скрываемой части (view1) и всегда видимой части (view2).Я хочу анимировать появление и исчезновение view1 в два этапа:

  • , если view1 исчезает , 1) view1 исчезает, а затем 2) view2 движется вверх ( 1 ),
  • , если появляется view1 , 1) view2 движется вниз, а затем 2) view1 исчезает ( 2 ).

Это пока результат:

disappear transition appear transition

Проблема в том, что sceneRoot меняет свои границы сразу же, как только view1 меняет видимость.view3 переходит в новое положение, делая исчезающий переход выглядящим обрезанным.

В идеале, я бы хотел, чтобы высота sceneRoot соответственно анимировалась.Если это недостижимо, я бы хотел, чтобы высота изменилась после , когда исчезнет переход, а не до его запуска.

Вот такой макет:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/scene_root"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/view_1"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:background="@android:color/holo_red_light"
            android:gravity="center"
            android:text="View 1 (Hideable)"
            android:textSize="24sp" />

        <TextView
            android:id="@+id/view_2"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:background="@android:color/holo_orange_light"
            android:gravity="center"
            android:text="View 2"
            android:textSize="24sp" />

    </LinearLayout>

    <TextView
        android:id="@+id/view_3"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:background="@android:color/holo_green_dark"
        android:gravity="center"
        android:text="View 3"
        android:textSize="24sp" />

</LinearLayout>

В этом упрощенном примере будет достаточно одного LinearLayout.В реальном сценарии, однако, уплощение компоновки не так легко достижимо.

Вот как я могу изменить видимость view1:

private fun toggleView1Visibility() {
    TransitionManager.endTransitions(sceneRoot)

    val isView1Appearing = view1.visibility != View.VISIBLE

    TransitionManager.beginDelayedTransition(
        sceneRoot,
        createTransition(isView1Appearing)
    )

    view1.visibility = if (isView1Appearing) View.VISIBLE else View.GONE
}

private fun createTransition(
    isView1Appearing: Boolean
): Transition {
    val view1Fade = Fade().apply {
        addTarget(view1)
        duration = 750
    }

    val view2ChangeBounds = ChangeBounds().apply {
        addTarget(view2)
        duration = 750
    }

    return TransitionSet().apply {
        ordering = TransitionSet.ORDERING_SEQUENTIAL

        if (isView1Appearing) {
            addTransition(view2ChangeBounds)
            addTransition(view1Fade)
        } else {
            addTransition(view1Fade)
            addTransition(view2ChangeBounds)
        }
    }
}

Какие опции нужно исправить, исчезаютпереход не прибегая к компоновке сглаживания?

спасибо.

Ответы [ 2 ]

1 голос
/ 07 июля 2019

Очевидно, что цели перехода не должны быть прямыми потомками корня сцены.

Добавление большего количества целей к ChangeBounds() добилось цели:

private fun createTransition(
        isView1Appearing: Boolean
): Transition {
    val view1Fade = Fade().apply {
        addTarget(view1)
        duration = 750
    }

    val changeBounds = ChangeBounds().apply {
        addTarget(sceneRoot)

        addTarget(view2)
        addTarget(view3)

        duration = 750
    }

    return TransitionSet().apply {
        ordering = TransitionSet.ORDERING_SEQUENTIAL

        if (isView1Appearing) {
            addTransition(changeBounds)
            addTransition(view1Fade)
        } else {
            addTransition(view1Fade)
            addTransition(changeBounds)
        }
    }
}

Надеюсь, это кому-нибудь пригодится.

0 голосов
/ 07 июля 2019

Отлично, если вы нашли ответ.Здесь я также добавляю ответ, хотя он на Java, потому что я мало что знаю о kotlin.

 private void toggleView1Visibility() {

        final int originalDimension = sceneRoot.getHeight();
        final int newDimension =sceneRoot.getHeight();


        Boolean isView1Appearing = view1.getVisibility() != View.VISIBLE;

        TransitionManager.beginDelayedTransition(sceneRoot, new TransitionSet()
                .addTransition(new ChangeBounds()));
        if (isView1Appearing){
            ViewGroup.LayoutParams params = sceneRoot.getLayoutParams();
            params.height = newDimension;
            sceneRoot.setLayoutParams(params);
            view1.setVisibility(View.VISIBLE );
        }

        else {
            TransitionManager.beginDelayedTransition(sceneRoot, new TransitionSet()
                    .addTransition(new ChangeBounds()));

            ViewGroup.LayoutParams params = sceneRoot.getLayoutParams();
            params.height = originalDimension;
            sceneRoot.setLayoutParams(params);
            view1.setVisibility(View.GONE);
        }
    }

Помните, что sceneroot является родительским LL макета.

...