Android,layoutParams 是否指向父视图而不是视图本身?

Android, does layoutParams points on parent view and not the view itself?

我在尝试动态更新视图的 layoutParams 时遇到问题。

要更新的视图是 ConstraintLayout,我想动态更改它 app:layout_constraintDimensionRatio 属性。

片段XML:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".LevelFragment">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/board"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginStart="32dp"
            android:layout_marginEnd="32dp"
            android:layout_marginTop="32dp"
            android:layout_marginBottom="32dp"
            android:background="@color/black"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintDimensionRatio="1:1"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

        </androidx.constraintlayout.widget.ConstraintLayout>

</FrameLayout>

但是当我尝试从 Kotlin 片段代码更改它时

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    board = view.findViewById(R.id.board)
    // Set ratio
    val layoutParams = board!!.layoutParams as ConstraintLayout.LayoutParams
    layoutParams.dimensionRatio = "5:1"
    board!!.layoutParams = layoutParams
}

调试构建后失败并出现此错误:

android.widget.FrameLayout$LayoutParams cannot be cast to androidx.constraintlayout.widget.ConstraintLayout$LayoutParams

所以,我想知道为什么它抱怨将 FrameLayout 转换为 ConstraintLayout,因为 layoutParams 取自 board 视图,这是一个 ConstraintLayout...

paramsLayout 是否引用父视图而不是视图本身?

如果是,如何更新视图 dimensionRatio 属性 ?

谢谢!

LayoutParams是parentViewGroup用来布局其children的参数。每个 child 都有自己的 LayoutParams,它有一个基于其 parent 类型的特定类型。即 FrameLayout 的 children 有 FrameLayout.LayoutParams 作为他们的 LayoutParams 和 children of LinearLayoutLinearLayout.LayoutParams 作为他们的 LayoutParams 等等。它们也不能互相转换,这意味着你不能将 LinearLayout.LayoutParams 转换为 FrameLayout.LayoutParams,因为它们有不同的 LayoutParams 实现。但所有 LayoutParams 都已扩展 ViewGroup.LayoutParams,因此将它们转换为 ViewGroup.LayoutParams 是安全的。
在您的情况下,您正在将 board.layoutParams 转换为 ConstraintLayout.LayoutParams 但由于 board 的 parent 是 FrameLayout 那么它的 LayoutParams 是类型 FrameLayout.LayoutParams 并且无法转换为 ConstraintLayout.LayoutParams
如果你想解决这个问题,你必须用 ConstraintLayout.
替换 board 的 parent,这是 FrameLayout 如果您想了解 LayoutParams 的工作原理,您也可以阅读 here