I got a problem when trying to update dynamically the layoutParams
of a view.
The view to update is a ConstraintLayout
, and I want to dynamically change it's app:layout_constraintDimensionRatio
property.
The fragment 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>
But when I try to change it from Kotlin fragment code
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
}
It fails with this error after debug build :
android.widget.FrameLayout$LayoutParams cannot be cast to androidx.constraintlayout.widget.ConstraintLayout$LayoutParams
So, I'm wondering why it complains about FrameLayout to ConstraintLayout cast, because the layoutParams
is taken from the board
View, which is a ConstraintLayout
...
Does the paramsLayout refers to the parent view and not the view itself ?
And if so, how to update view dimensionRatio
property ?
Thanks !
LayoutParams
are the parameters which parent ViewGroup
uses to layout its children. Each child has its own LayoutParams
which has a specific type based on type of its parent. i.e. children of FrameLayout
has FrameLayout.LayoutParams
as their LayoutParams
and children of LinearLayout
has LinearLayout.LayoutParams
as their LayoutParams
and so on. Also they can not get cast to each other, it means you can not cast LinearLayout.LayoutParams
to FrameLayout.LayoutParams
since they have different implementation of LayoutParams
. But all of LayoutParams
have exteded ViewGroup.LayoutParams
, so it is safe to cast them to ViewGroup.LayoutParams
.
In your case you are casting board.layoutParams
to ConstraintLayout.LayoutParams
but since parent of board
is a FrameLayout
then its LayoutParams
is of type FrameLayout.LayoutParams
and can not get cast to ConstraintLayout.LayoutParams
.
If you want to fix this you have to replace parent of board
which is a FrameLayout
with a ConstraintLayout
.
Also you can read here if you want to see how LayoutParams
works.