在 ConstraintLayout 中制作自定义视图高度匹配约束

问题描述

我正在构建一个简单的自定义视图,目前它只是一个基本的矩形容器,因为我在 ConstraintLayout 上遇到了一些问题。

The main layout setup. The textView is constrained to the parent while the Wire view is constrained to the parent and the top to the bottom of the textView

在 onMeasure 方法中,我试图使视图的高度与垂直约束相匹配。我的意思是我希望我的视图高度填充两个垂直约束之间的空间。 网上找不到相关的代码,有谁知道怎么做吗?

解决方法

为了匹配约束,您需要将宽度/高度设置为零,这样视图将占用约束声明的空间,例如:

<?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_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/mytv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="text view"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:text="Your wire view"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/mytv" />

</androidx.constraintlayout.widget.ConstraintLayout>

看看“wire”视图,我设置了高度和 0,然后它占用了由它们的约束定义的所有空间。

Layout example

,

这是对上述 Nestor Perez 解决方案的补充,但我将专注于解决高度和宽度的 onMeasure() 的 Kotlin 代码。

首先我们声明widthheight变量并将它们设置为0。

     class CustomRectangle @JvmOverloads constructor(context: Context,attrs: AttributeSet? = null,defStyleAttr: Int = 0) : View(context,attrs,defStyleAttr) {
    
        //width and height variables
        private var widthSize = 0
        private var heightSize = 0 

//PAINT OBJECT
    private val paint = Paint().apply {

        style = Paint.Style.FILL
        
    }
......}

在测量内部,我们使用 resolveSizeAndState() 方法来计算 2 个维度。然后我们设置高度和宽度,如下所示。

//ON_MEASURE
    override fun onMeasure(widthMeasureSpec: Int,heightMeasureSpec: Int) {
        val minWidth: Int = paddingLeft + paddingRight + suggestedMinimumWidth
        val w: Int = resolveSizeAndState(minWidth,widthMeasureSpec,1)
        val h: Int = resolveSizeAndState(MeasureSpec.getSize(w),heightMeasureSpec,0)
        widthSize = w
        heightSize = h
        setMeasuredDimension(w,h)
    }

然后onDraw()我们使用解析的高度宽度绘制自定义矩形。

override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

paint.color = Color.Whatever_Color
canvas.drawRect(0f,0f,widthSize.toFloat(),heightSize.toFloat(),paint)
       

    }

然后正如 Nestor Perez 在上面解释的那样,我们将宽度和高度设置为 0dp。

<com.custombutton
        android:id="@+id/custom_button"
        android:layout_width="0dp"
        android:layout_height="0dp" ..../>

干杯