如何将 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 的正确位置(将 top
和 left
位置设置在你的红色方块下方)
类似
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>
我有这样的自定义视图:
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 的正确位置(将 top
和 left
位置设置在你的红色方块下方)
类似
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>