I've created custom View
which extends ConstraintLayout
. I want to implement onMeasure() because I've notices issues with size customization on different components with different sizes and/or paddings/margins.
This is my View's layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:background="@android:color/transparent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:button="@drawable/drawable_state"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/animation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:lottie_rawRes="@raw/animation_json"
app:lottie_speed="2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:lottie_autoPlay="false"
app:lottie_loop="false"/>
</androidx.constraintlayout.widget.ConstraintLayout>
I've came up with something like this:
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val widthMode = MeasureSpec.getMode(widthMeasureSpec)
val widthSize = MeasureSpec.getSize(widthMeasureSpec)
val heightMode = MeasureSpec.getMode(heightMeasureSpec)
val heightSize = MeasureSpec.getSize(heightMeasureSpec)
val width = when(widthMode) {
MeasureSpec.EXACTLY -> widthSize
MeasureSpec.AT_MOST -> min(STANDARD_WIDTH, widthSize)
else -> STANDARD_WIDTH
}
val height = when(heightMode) {
MeasureSpec.EXACTLY -> heightSize
MeasureSpec.AT_MOST -> min(STANDARD_HEIGHT, heightSize)
else -> STANDARD_HEIGHT
}
setMeasuredDimension(width, height);
}
But it turns out since it is container with children I have to take care of it too. So I've searched for this here And found implementation which includes child Views:
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val widthMode = MeasureSpec.getMode(widthMeasureSpec)
val widthSize = MeasureSpec.makeMeasureSpec(widthMeasureSpec, MeasureSpec.EXACTLY)
val heightMode = MeasureSpec.getMode(heightMeasureSpec)
val heightSize = MeasureSpec.makeMeasureSpec(heightMeasureSpec, MeasureSpec.EXACTLY)
for (index in 0 until childCount) {
val child: View = getChildAt(index)
child.measure(widthSize, heightSize)
}
val width = when (widthMode) {
MeasureSpec.EXACTLY -> widthSize
MeasureSpec.AT_MOST -> min(STANDARD_WIDTH, widthSize)
else -> STANDARD_WIDTH
}
val height = when (heightMode) {
MeasureSpec.EXACTLY -> heightSize
MeasureSpec.AT_MOST -> min(STANDARD_HEIGHT, heightSize)
else -> STANDARD_HEIGHT
}
setMeasuredDimension(width, height)
}
It seems like this does nothing and still my Views are not visible so probably size is still 0 for them.
I can't say I understand this and I don't feel good with layouts. onMeasure() is kinda new for me and I've never had to implement it.
I would be really grateful if someone could tell me what I am doing wrong.
question from:
https://stackoverflow.com/questions/65922372/constraintlayout-onmeasure-for-viewgroup 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…