gpt4 book ai didi

android - 如何在 ItemDecoration 中绘制 View ?

转载 作者:太空宇宙 更新时间:2023-11-03 12:26:43 25 4
gpt4 key购买 nike

我已经知道如何在 ItemDecoration 中绘制东西,但现在我想在 ItemDecoration 中绘制一个 View

由于设置有点复杂,我创建了一个sample project可以重现问题。

我想要实现的目标

我有一个包含 20 个项目的 RecyclerView,只显示数字。我想在第 5 项上方添加一个带有文本“This is Number 5”的黑色标题。

当然,这是我的真实问题的简化版本,在我的真实问题中我必须通过 ItemDecoration 来完成,所以请不要给出不使用 ItemDecoration 的替代方案。

问题

如下图所示,装饰尺寸正确,可以绘制xml的第一层(有android:background="@color/black");但不包含应该显示“This is Number 5”的 TextView 的 subview 。

enter image description here

我现在该怎么做

FiveHeaderDecoration.kt:

class FiveHeaderDecoration: RecyclerView.ItemDecoration() {

private var header: Bitmap? = null
private val paint = Paint()

override fun getItemOffsets(outRect: Rect?, view: View?, parent: RecyclerView?, state: RecyclerView.State?) {
val params = view?.layoutParams as? RecyclerView.LayoutParams
if (params == null || parent == null) {
super.getItemOffsets(outRect, view, parent, state)
} else {
val position = params.viewAdapterPosition
val number = (parent.adapter as? JustAnAdapter)?.itemList?.getOrNull(position)
if (number == 5) {
outRect?.set(0, 48.dp(), 0, 0)
} else {
super.getItemOffsets(outRect, view, parent, state)
}
}
}

override fun onDraw(c: Canvas?, parent: RecyclerView?, state: RecyclerView.State?) {
initHeader(parent)
if (parent == null) return
val childCount = parent.childCount
for (i in 0 until childCount) {
val view = parent.getChildAt(i)
val position = parent.getChildAdapterPosition(view)
val number = (parent.adapter as? JustAnAdapter)?.itemList?.getOrNull(position)
if (number == 5) {
header?.let {
c?.drawBitmap(it, 0.toFloat(), view.top.toFloat() - 48.dp(), paint)
}
} else {
super.onDraw(c, parent, state)
}
}
}

private fun initHeader(parent: RecyclerView?) {
if (header == null) {
val view = parent?.context?.inflate(R.layout.decoration, parent, false)
val bitmap = Bitmap.createBitmap(parent?.width?:0, 40.dp(), Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
view?.layout(0, 0, parent.width, 40.dp())
view?.draw(canvas)
header = bitmap
}
}

}

您可以在示例项目中找到其他类。但我猜他们并没有真正相关。

如您所见,我尝试先对 View 进行布局并将其绘制为位图。这是因为我只能在 onDraw() 中在 Canvas 上绘制一些东西,但不能膨胀 View (我什至没有 ViewGroupaddView() )。

并且通过使用调试器,我已经可以看到在 initHeader() 中生成的位图只是一 block 黑色。所以问题可能在于我如何initHeader()

最佳答案

想通了(哎呀我的赏金)

为了正确创建一个View,需要3个步骤:

  1. 测量(view.measure())
  2. 布局(view.layout())
  3. 绘制(view.draw())

通常这些由父 ViewGroup 完成,或在 addView() 中完成。但是现在因为我们没有做任何这些,我们需要自己调用所有这些。

问题显然是我错过了第一步。

所以initHeader方法应该是:

private fun initHeader(parent: RecyclerView?) {
if (header == null) {
val view = parent?.context?.inflate(R.layout.decoration, parent, false)
val bitmap = Bitmap.createBitmap(parent?.width?:0, 40.dp(), Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
val widthSpec = View.MeasureSpec.makeMeasureSpec(parent?.width ?: 0, View.MeasureSpec.EXACTLY)
val heightSpec = View.MeasureSpec.makeMeasureSpec(40.dp(), View.MeasureSpec.EXACTLY)
view?.measure(widthSpec, heightSpec)
view?.layout(0, 0, parent.width, 40.dp())
view?.draw(canvas)
header = bitmap
}
}

请注意,widthSpec 和 heightSpec 将根据您的用例而有所不同。那是另一个话题,所以我不在这里解释。

关于android - 如何在 ItemDecoration 中绘制 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50878305/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com