I have a custom view based on ConstraintLayout.
This view has dynamic width depending on actual content width. I am doing manual measuring of my custom view via onMeasure.
I also have a button which I expect to be centered horizontally. It not actually centering so I try to center programmically in onLayout. It seems layout method does not work as expected:
How to fix this?
This is my Custom view code:
class SgBox(context: Context, attrs: AttributeSet): ConstraintLayout(context, attrs) {
private val binding: ViewSgBoxBinding
private val titles: List<TextView>
private val values: List<TextView>
private val centerable: List<View>
init {
binding = ViewSgBoxBinding.inflate(LayoutInflater.from(context), this)
titles = listOf(binding.title1, binding.title2)
values = listOf(binding.value1, binding.value2)
centerable = listOf(binding.bntMore)
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val desiredWidth = titles.maxWidth+
values.maxWidth +
paddingStart+paddingEnd+20
setMeasuredDimension(desiredWidth, measuredHeight)
}
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
super.onLayout(changed, left, top, right, bottom)
values.forEach {
val r = measuredWidth - paddingEnd
it.layout(r-it.measuredWidth, it.top, r, it.bottom)
}
centerable.forEach {
val s = measuredWidth/2 - it.measuredWidth/2
it.layout(it.left+s, it.top, it.right+s, it.bottom)
}
}
private val List<View>.maxWidth get() = maxOf { it.measuredWidth }
}
By the way. Notice that "2.1" has different color, while I expect it to be the same color as "P2" or "Param 1" - both TextView just do not have a color specified. Why the color is different?
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="@+id/title1"
android:text="Param 1:"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/value1"
android:text="-464.44"
android:textColor="@color/black"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBaseline_toBaselineOf="@id/title1"
app:layout_constraintStart_toStartOf="parent"/>
<View
android:id="@+id/divider1"
android:layout_width="wrap_content"
android:layout_height="2dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/title1"
android:background="@color/teal_700"/>
<TextView
android:id="@+id/title2"
android:text="P2:"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/divider1" />
<TextView
android:id="@+id/value2"
android:text="2.1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBaseline_toBaselineOf="@id/title2"
app:layout_constraintStart_toEndOf="@id/barrier_titles"
app:layout_constraintEnd_toEndOf="parent"/>
<View
android:id="@+id/divider2"
android:layout_width="wrap_content"
android:layout_height="2dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/title2"
android:background="@color/teal_700"/>
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier_titles"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="2dp"
app:barrierDirection="end"
app:constraint_referenced_ids="title1,title2"/>
<Button
android:id="@+id/bnt_more"
android:text="More"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/divider2" />
</merge>
