ConstraintLayout:第二个视图捕捉到父视图而不是自定义视图的底部
ConstraintLayout: Second view snaps to parent instead of bottom of custom view
我在约束布局中有两个视图,一个是自定义的,一个是标准的 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_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.example.app.DrawCharacterView
android:id="@+id/drawCharacterView"
android:layout_width="300dp"
android:layout_height="300dp"
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_width="30dp"
android:layout_height="30dp"
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)
}
}
You need to 也将 attrs
传递给您的 View
构造函数:
To allow Android Studio to interact with your view, at a minimum you must provide a constructor that takes a Context and an AttributeSet object as parameters. This constructor allows the layout editor to create and edit an instance of your view.
这确实是关于布局编辑器的,但我假设重要的 ConstraintLayout
属性是必需的,以便其他视图可以在您的自定义视图上定义约束(我不知道有关它们的详细信息重新解决,但这是有道理的)。
仅供参考,如果您开始输入以下内容:
DrawCharacterView : View
将光标放在 View
的末尾,按 Alt+Enter(或您建议的任何快捷方式,或单击弹出的灯泡图标),您可以选择 添加 Android 使用“@JvmOverloads”查看构造函数。这将生成:
class DrawCharacterView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr)
节省您的时间,并自动传递 attrs
和 defStyleAttr
参数/一些默认值,这通常是您想要的!
我在约束布局中有两个视图,一个是自定义的,一个是标准的 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_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.example.app.DrawCharacterView
android:id="@+id/drawCharacterView"
android:layout_width="300dp"
android:layout_height="300dp"
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_width="30dp"
android:layout_height="30dp"
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)
}
}
You need to 也将 attrs
传递给您的 View
构造函数:
To allow Android Studio to interact with your view, at a minimum you must provide a constructor that takes a Context and an AttributeSet object as parameters. This constructor allows the layout editor to create and edit an instance of your view.
这确实是关于布局编辑器的,但我假设重要的 ConstraintLayout
属性是必需的,以便其他视图可以在您的自定义视图上定义约束(我不知道有关它们的详细信息重新解决,但这是有道理的)。
仅供参考,如果您开始输入以下内容:
DrawCharacterView : View
将光标放在 View
的末尾,按 Alt+Enter(或您建议的任何快捷方式,或单击弹出的灯泡图标),您可以选择 添加 Android 使用“@JvmOverloads”查看构造函数。这将生成:
class DrawCharacterView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr)
节省您的时间,并自动传递 attrs
和 defStyleAttr
参数/一些默认值,这通常是您想要的!