Как анимировать изменение высоты видов внутри LinearLayout? - PullRequest
0 голосов
/ 13 ноября 2018

Я работаю над приложением Android 4+, которое использует довольно простую компоновку: несколько представлений складываются с использованием LinearLayout в ScrollView

<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:ignore="HardcodedText,UseCompoundDrawables,UselessParent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:focusableInTouchMode="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" 

        <!-- Top Container -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" 

            <Button... />
        </LinearLayout>

        <!-- Hidden Container -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" 

            ... Some Content ...

        </LinearLayout>

        <!-- Bottom Container -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" 

            ... Some Content ...

        </LinearLayout>
    </LinearLayout>
</ScrollView>

HiddenContainer не должен быть виден при создании макета. Таким образом, в начале BottomContainer находится непосредственно под TopContainer. Щелчок по Button в пределах TopContainer переключает видимость HiddenContainer.

Делая это с hiddenContainer.setVisibility(hiddenContainer.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE), работает без проблем. Однако это не выглядит хорошо, когда вид внезапно появляется или исчезает. Вместо этого я хотел бы оживить изменение.

Я был удивлен, что мне не удалось найти простое решение для этого:

  • Использование android:animateLayoutChanges="true" работает, однако я не могу управлять анимацией.
  • При использовании ValueAnimator для изменения hiddenContainer.setScaleY(...) дает мне контроль над анимацией setScaleY(0) делает контейнер невидимым, не уменьшая пространство, которое он занимает в макете.
  • Использование ValueAnimator для изменения hiddenContainer.setHeight(...) может работать, однако я не хочу использовать фиксированное значение высоты при отображении контейнера (например, hiddenContainer.setHeight(300)), но высоту, которая определяется содержимым контейнеров.

Итак, как это решить?

1 Ответ

0 голосов
/ 13 ноября 2018

Для анимации изменений макета (альфа, видимость, высота и т. Д.) Вы можете использовать TransitionManager. Например: у меня есть три статических метода, и я использую их, когда хочу анимировать изменения макета:

public static final int DURATION = 200;

public static void beginAuto(ViewGroup viewGroup) {
    AutoTransition transition = new AutoTransition();
    transition.setDuration(DURATION);
    transition.setOrdering(TransitionSet.ORDERING_TOGETHER);
    TransitionManager.beginDelayedTransition(viewGroup, transition);
}

public static void beginFade(ViewGroup viewGroup) {
    Fade transition = new Fade();
    transition.setDuration(DURATION);
    TransitionManager.beginDelayedTransition(viewGroup, transition);
}

public static void beginChangeBounds(ViewGroup viewGroup) {
    ChangeBounds transition = new ChangeBounds();
    transition.setDuration(DURATION);
    TransitionManager.beginDelayedTransition(viewGroup, transition);
}

А если вы хотите анимировать изменения макета, вы можете просто вызвать один из следующих методов перед изменением макета:

beginAuto(hiddenContainerParentLayout);
hiddenContainer.setVisibility(hiddenContainer.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE)
...