📜  获得垂直布局组统一的首选高度 (1)

📅  最后修改于: 2023-12-03 15:11:53.646000             🧑  作者: Mango

获得垂直布局组统一的首选高度

在进行垂直布局时,通常需要让一组视图按一定的间距排列,以便更好地呈现相关信息。如果我们希望这组视图在布局时具有一致的高度,而这个高度还是最佳的首选高度,那该怎么做呢?本文将介绍如何通过几种方式获得垂直布局组的一致首选高度。

使用LinearLayout

LinearLayout 是最基础的垂直布局,可以使用它来布局一组视图,其中的子视图可以使用 layout_weight 属性来控制它们的高度。

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

    <View
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <View
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <View
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

</LinearLayout>

这个例子中,我们在每个视图中设置了 layout_weight 为 1,表示它们在垂直布局中的高度应该是一致的。这样可以确保每个视图都具有相同的首选高度。但是,这个高度并不能完全保证是最佳的高度。

使用ConstraintLayout

我们可以使用 ConstraintLayout 来获得一组子视图的首选高度。假设我们有以下三个视图:

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <View
        android:id="@+id/view1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:id="@+id/view2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        app:layout_constraintTop_toBottomOf="@id/view1" />

    <View
        android:id="@+id/view3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        app:layout_constraintTop_toBottomOf="@id/view2" />

</androidx.constraintlayout.widget.ConstraintLayout>

这里,我们使用 ConstraintLayout 来布局这三个视图,并且将它们按顺序垂直排列。由于每个视图都使用了 wrap_content 的高度属性,所以它们的高度是根据内容自动计算出来的。

接下来,我们可以使用 Kotlin 代码来获取 ConstraintLayout 的高度,并计算出三个视图中的最大高度:

val constraintLayout = findViewById<ConstraintLayout>(R.id.constraint_layout)

constraintLayout.viewTreeObserver.addOnGlobalLayoutListener(object :
    ViewTreeObserver.OnGlobalLayoutListener {
    override fun onGlobalLayout() {
        val view1 = findViewById<View>(R.id.view1)
        val view2 = findViewById<View>(R.id.view2)
        val view3 = findViewById<View>(R.id.view3)

        val maxHeight = max(
            view1.height,
            max(view2.height, view3.height)
        )

        // 用 maxHeight 来设置三个视图的高度
        view1.height = maxHeight
        view2.height = maxHeight
        view3.height = maxHeight

        // 必须 remove 监听器以避免重复调用
        constraintLayout.viewTreeObserver.removeOnGlobalLayoutListener(this)
    }
})

我们首先获取 ConstraintLayout 的实例,并使用 addOnGlobalLayoutListener 方法添加一个全局布局监听器。当 ConstraintLayout 完成布局时,这个方法会被调用。

在监听器中,我们获取三个视图的实例,并使用 max 方法来计算出它们的最大高度。然后,我们把这个高度应用到三个视图中。这样,我们就获得了一组视图的一致首选高度。