通过 onLayout 在 ConstraintLoyout 中将元素水平居中

Center an element horizontally in a ConstraintLoyout via onLayout

提问人:Solvek 提问时间:11/2/2023 更新时间:11/2/2023 访问量:23

问:

我有一个基于 . 此视图具有动态宽度,具体取决于实际内容宽度。我正在通过 手动测量我的自定义视图。 我还有一个按钮,我希望它水平居中。它实际上没有居中,所以我尝试以编程方式居中。似乎方法没有按预期工作:ConstraintLayoutonMeasureonLayoutlayout

enter image description here

如何解决这个问题?

这是我的自定义视图代码:

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 }
}

顺便一提。请注意,“2.1”具有不同的颜色,而我希望它与“P2”或“Param 1”的颜色相同 - 两个 TextView 都没有指定颜色。为什么颜色不同?

<?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>
android-layout android-custom-view

评论


答: 暂无答案