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

问题描述

尝试动态更新视图的 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 无法转换为 androidx.constraintlayout.widget.ConstraintLayout$LayoutParams

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

paramsLayout 是指父视图而不是视图本身吗?

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

谢谢!

解决方法

LayoutParams 是父 ViewGroup 用于布局其子项的参数。每个子级都有自己的 LayoutParams,它具有基于其父级类型的特定类型。即 FrameLayout 的孩子有 FrameLayout.LayoutParams 作为他们的 LayoutParamsLinearLayout 的孩子有 LinearLayout.LayoutParams 作为他们的 LayoutParams 等等。此外,它们不能相互转换,这意味着您不能将 LinearLayout.LayoutParams 转换为 FrameLayout.LayoutParams,因为它们具有不同的 LayoutParams 实现。但是所有 LayoutParams 都已扩展 ViewGroup.LayoutParams,因此将它们强制转换为 ViewGroup.LayoutParams 是安全的。
在您的情况下,您将 board.layoutParams 强制转换为 ConstraintLayout.LayoutParams,但由于 board 的父级是 FrameLayout,因此其 LayoutParams 的类型为 FrameLayout.LayoutParams 并且可以不会被强制转换为 ConstraintLayout.LayoutParams
如果你想解决这个问题,你必须用 board 替换 FrameLayout 的父级,它是一个 ConstraintLayout
如果您想了解 LayoutParams 的工作原理,也可以阅读 here

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...