【问题标题】:Make custom view height match constraints in ConstraintLayout在 ConstraintLayout 中使自定义视图高度匹配约束
【发布时间】:2021-09-29 19:45:47
【问题描述】:

我正在构建一个简单的自定义视图,目前它只是一个基本的矩形容器,因为我在使用 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 方法中,我试图使视图的高度与垂直约束相匹配。我的意思是我希望我的视图高度填充两个垂直约束之间的空间。 网上没找到相关代码,有大神知道怎么弄吗?

【问题讨论】:

  • 你好,你能从你的视图中放一些代码来展示它是如何实现的吗?
  • 它的 onMeasure 方法仍然是空的,因为我不知道如何使我的自定义视图的高度匹配约束。
  • 使用 ConstraintParams 将其高度设置为 0,父级将使其填充约束。

标签: java android kotlin android-custom-view android-constraintlayout


【解决方案1】:

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

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

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

【讨论】:

  • 问题是“wire”是一个自定义视图,所以我必须自己实现这个行为。
  • 这不是真的。如果需要,您可以将测量留给 Android 框架。
  • 你不必自己实现任何东西来实现你想要的,只需将自定义视图与包装内容一起保留并让父 ConstraintLayout 完成他的工作
【解决方案2】:

这是对 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() 我们使用解析后的 heightwidth 绘制自定义矩形。

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" ..../>

干杯

【讨论】:

    猜你喜欢
    • 2019-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-03
    • 2015-08-30
    • 2020-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多