问题描述
尝试动态更新视图的 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
作为他们的 LayoutParams
,LinearLayout
的孩子有 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。