如何设置LinearLayout内视图高度变化的动画



我正在开发一款Android 4+应用程序,该应用程序使用非常简单的布局:在ScrollView中使用LinearLayout堆叠多个视图

<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在创建布局时不应可见。因此在开始时CCD_ 4直接位于CCD_。单击TopContainer中的Button可切换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)(,而是使用由容器内容决定的高度

那么,如何解决这个问题呢

为了对布局(alpha、可见性、高度等(的更改进行动画处理,您可以使用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)

最新更新