Android 如何设置视图高度的动画?

Android 如何设置视图高度的动画?,android,android-layout,android-constraintlayout,Android,Android Layout,Android Constraintlayout,目标 我想能够动画的高度,两个视图堆叠在一列中彼此的顶部。可能出现三种情况: 俯视图覆盖了所有可用空间,因此 底部视图变得不可见 底部视图覆盖所有可用空间,因此顶部视图不可见 两个视图都可见。如果俯视图占总可用高度的30%,那么俯视图应占总可用高度的70% 问题 如果我在20%到80%之间设置俯视图高度的动画,效果会很好。动画正是我想要的;一个视图的高度增加,另一个视图的高度减少,而两个视图的宽度保持不变 但是,如果我将俯视图的高度设置为0%到100%之间,事情会变得很奇怪: 我想这种行为可

目标
我想能够动画的高度,两个视图堆叠在一列中彼此的顶部。可能出现三种情况:

  • 俯视图覆盖了所有可用空间,因此 底部视图变得不可见
  • 底部视图覆盖所有可用空间,因此顶部视图不可见
  • 两个视图都可见。如果俯视图占总可用高度的30%,那么俯视图应占总可用高度的70%
问题
如果我在20%到80%之间设置俯视图高度的动画,效果会很好。动画正是我想要的;一个视图的高度增加,另一个视图的高度减少,而两个视图的宽度保持不变

但是,如果我将俯视图的高度设置为0%到100%之间,事情会变得很奇怪:

我想这种行为可以解释,因为在最后的情况下,推出视图的高度和宽度都是0。请注意,我使用的是ConstraintLayout,但没有这方面的要求。我只是觉得这是最容易做到的事。我试过没有动画顶视图,但是中间有一个指南,但也没用。

奖金问题
如果其中一个视图100%可见,那么处理这两个视图之间的边界的最佳方法是什么?当然,最终视图和父视图之间不应该有双边距(或者根本没有)

class MainActivity:AppCompatActivity(){
私有变量cnt=0
重写创建时的乐趣(savedInstanceState:Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val root=findviewbyd(R.id.main_容器)
固定计时器(
周期=时间单位。秒。托米利斯(3)
) {
val百分比=何时(cnt++){
0->0.0f
2->1.0f
else->0.5f
}
root.post{
val newConstraintSet=ConstraintSet().apply{clone(root)}
newConstraintSet.ConstraintPercentHeight(R.id.top,百分比)
TransitionManager.beginDelayedTransition(根)
newConstraintSet.applyTo(根)
}
如果(cnt>3)cnt=0
}
}
}


我建议从constraintlayout迁移到motionlayout(这是前者的扩展),这样您就可以轻松地在两个约束集之间进行转换。谢谢您的建议,但这不会产生同样的问题吗?在我发布的示例中,我已经在约束集之间进行了转换。我的意思是,您只对俯视图的百分比高度设置动画。使用ML,您可以更改场景中给您带来麻烦的百分比:。在0%或100%时,将没有垂直链,您可以将“边距”设置为任何仍可见的视图。此外,您还可以直接从studio使用motion layout editor,这样您就可以在不需要构建和安装的情况下立即看到动画。我非常想了解MotionLayout,所以我尝试了一下。我尽可能在0%到100%之间设置动画,但我不确定如何继续。例如,当到达延伸时,如何删除边距?你能给我指一些文件吗?再次感谢。只需在最终场景的“底部视图约束集”中将布局边距设置为0,它们应该得到尊重并设置动画
class MainActivity : AppCompatActivity() {

    private var cnt = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val root = findViewById<ConstraintLayout>(R.id.main_container)

        fixedRateTimer(
            period = TimeUnit.SECONDS.toMillis(3)
        ) {
            val percentage = when (cnt++) {
                0 -> 0.0f
                2 -> 1.0f
                else -> 0.5f
            }

            root.post {
                val newConstraintSet = ConstraintSet().apply { clone(root) }
                newConstraintSet.constrainPercentHeight(R.id.top, percentage)
                TransitionManager.beginDelayedTransition(root)
                newConstraintSet.applyTo(root)
            }

            if (cnt > 3) cnt = 0
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/main_container"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <View
        android:id="@+id/top"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="16dp"
        android:layout_marginEnd="16dp"
        android:layout_marginBottom="16dp"
        android:layout_marginTop="16dp"
        app:layout_constraintBottom_toTopOf="@+id/bottom"
        app:layout_constraintHeight_percent="0.5"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:background="#ff0"
        />

    <View
        android:id="@+id/bottom"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="16dp"
        android:layout_marginEnd="16dp"
        android:layout_marginBottom="16dp"
        app:layout_constraintTop_toBottomOf="@+id/top"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:background="#f0f"
        />


</androidx.constraintlayout.widget.ConstraintLayout>