ConstraintLayout:第二个视图捕捉到父视图而不是自定义视图的底部

Posted

技术标签:

【中文标题】ConstraintLayout:第二个视图捕捉到父视图而不是自定义视图的底部【英文标题】:ConstraintLayout: Second view snaps to parent instead of bottom of custom view 【发布时间】:2022-01-12 02:39:57 【问题描述】:

我在约束布局中有两个视图,一个是自定义视图,一个是标准 ImageView。我想将 ImageView 放在自定义视图下方。我在 ImageView 上设置 app:layout_constraintTop_toBottomOf 将其附加到自定义视图的底部。

但是,我的 ImageView 会捕捉到父布局的顶部,而不是自定义视图的底部。这既发生在 android Studio 的设计视图中,也发生在运行应用程序时。

我该如何解决这个问题?

activity_main.xml

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    tools:context=".MainActivity">

    <com.example.app.DrawCharacterView
        android:id="@+id/drawCharacterView"
        android:layout_
        android:layout_
        android:layout_marginTop="16dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_
        android:layout_
        android:layout_marginTop="16dp"
        android:background="#F44336"
        android:padding="1dp"
        android:scaleType="fitCenter"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/drawCharacterView" />
</androidx.constraintlayout.widget.ConstraintLayout>

DrawCharacterView.kt

package com.example.app

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.util.AttributeSet
import android.view.View
import androidx.core.content.res.ResourcesCompat

class DrawCharacterView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyle: Int = 0
) : View(context) 
    private lateinit var extraCanvas: Canvas
    private lateinit var extraBitmap: Bitmap

    private val backgroundColor = ResourcesCompat.getColor(resources, R.color.black, null)

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) 
        super.onSizeChanged(w, h, oldw, oldh)

        if (::extraBitmap.isInitialized) extraBitmap.recycle()
        extraBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
        extraCanvas = Canvas(extraBitmap)
        extraCanvas.drawColor(backgroundColor)
    

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

        canvas.drawBitmap(extraBitmap, 0f, 0f, null)
    

【问题讨论】:

【参考方案1】:

You need to 也将 attrs 传递给您的 View 构造函数:

要允许 Android Studio 与您的视图交互,您至少必须提供一个以 Context 和 AttributeSet 对象作为参数的构造函数。此构造函数允许布局编辑器创建和编辑视图的实例。

这实际上是关于布局编辑器的,但我假设重要的 ConstraintLayout 属性是必需的,以便其他视图可以在您的自定义视图上定义约束(我不知道如何解决它们的详细信息,但是这是有道理的)。

仅供参考,如果您开始输入以下内容:

DrawCharacterView : View

将光标放在View 的末尾,按 Alt+Enter(或任何建议的快捷方式,或单击弹出的灯泡图标),您可以选择 Add Android View constructors using '@JvmOverloads '。这将生成:

class DrawCharacterView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr)

这样可以节省您的时间,并自动传递attrsdefStyleAttr 参数/一些默认值,这通常是您想要的!

【讨论】:

谢谢,这正是我的问题!

以上是关于ConstraintLayout:第二个视图捕捉到父视图而不是自定义视图的底部的主要内容,如果未能解决你的问题,请参考以下文章

ConstraintLayout使用中遇到的问题:同一行内的两个Textview,第二个被挤出屏幕的解决方案

Android Studio 2.3.1中ConstraintLayout下的布局对齐中心

CSS Scroll-Snapping 不断跳过它应该捕捉到的元素之一

从第二个视图返回到一个视图时 UIButton 不可点击

WPF 数据绑定到第二个视图

从 uitableviewcell 获取数据到第二个视图