如何将 XML 布局添加到自定义视图?

How to add XML layout to custom view?

我有这样的自定义视图:

class SquareView : View {

    private lateinit var mRectanglePaint: Paint


    constructor(context: Context?) : super(context) {
        init(null)
    }

    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
        init(attrs)
    }

    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        init(attrs)
    }

    constructor(
        context: Context?,
        attrs: AttributeSet?,
        defStyleAttr: Int,
        defStyleRes: Int
    ) : super(context, attrs, defStyleAttr, defStyleRes) {
        init(attrs)
    }

    private fun init(attrs: AttributeSet?) {

        mRectanglePaint = Paint().apply {
            isAntiAlias = true
            color = Color.RED
        }

    }


    override fun onDraw(canvas: Canvas) {
        canvas.apply {
            drawRectangle(this)
        }
    }

    private fun drawRectangle(canvas: Canvas) {
        val rect = Rect()
        rect.left = 100
        rect.right = rect.left + 100
        rect.top = 100
        rect.bottom = rect.top + 100

        canvas.drawRect(rect, mRectanglePaint)
    }

}

而且,这是我的 blue_square.xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:orientation="vertical"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_height="wrap_content">

    <View
        android:id="@+id/blue_square"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="#0000FF" />

</LinearLayout>

我想将此 XML 布局添加到我的视图中并将位置设置为红色方块的底部。

我添加了这段代码,但这次只出现了蓝色方块。

val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val view = inflater.inflate(R.layout.blue_square, this, true)

我想在自定义视图中包含蓝色方块并更改其位置。

我该怎么做?谢谢你的帮助。

当我说 2 种不同的方法时,第一种方法更详细一些,但我也会概述其他方法。

1) 首先是将 xml 膨胀并布局为 Bitmap,然后在正确的位置绘制该位图 Canvas

膨胀你的 xml 但不要将它附加到你的自定义视图或将它作为父级(因为它真的取代了你的自定义视图(膨胀的第二个和第三个参数)

例如

val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val xmlView = inflater.inflate(R.layout.blue_square, null, false)

将这个新视图绘制到位图

抱歉,这是 Java,但您可以将其转换为 Kotlin,因为您似乎正在使用它。

Canvas bitmapCanvas = new Canvas();
Bitmap bitmap = Bitmap.createBitmap(xmlView.getWidth(), xmlView.getHeight(), Bitmap.Config.ARGB_8888);

bitmapCanvas.setBitmap(bitmap);
xmlView.draw(bitmapCanvas);

然后在你的 onDraw 中将此位图绘制到你的 canvas 的正确位置(将 topleft 位置设置在你的红色方块下方)

类似

plainPaint = Paint().apply { isAntiAlias = true }
canvas.drawBitmap (bitmap, left, top, plainPaint)

请注意,这并没有经过严格测试,但它与我经常做的事情很相似。

2) 不要颠倒视图和视图组的正常层次结构,不要让您的 SquareView 自定义视图成为您的应用绘制的单一视图。您的 SquareView 自定义视图应该只绘制一个大到足以成为正方形的视图(您应该为您的自定义视图实现 onMeasure)。

然后一个 App 可以在里面做 xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:orientation="vertical"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_height="wrap_content">

    <SquareView
        android:id="@+id/custom_square"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <View
        android:id="@+id/blue_square"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="#0000FF" />

</LinearLayout>