我已经知道如何在ItemDecoration
中绘制物品,但现在我想在ItemDecoration
中绘制一个View
。
由于设置有点复杂,我创建了一个示例项目来重现这个问题。
我的目标
我有一个包含20个项目的RecyclerView
,仅显示数字。我想在第5个项目上方添加一个黑色标题,上面写着"This is Number 5"。
当然,这是我真正问题的简化版本,在我的真实问题中,我必须通过ItemDecoration来实现这一点,请不要提供不使用ItemDecoration的替代方法。
问题
如下截图所示,装饰的大小是正确的,xml的第一层(其中android:background="@color/black"
)可以绘制;但不包括应该显示"This is Number 5"的TextView
在内的子视图。
我现在如何做到这一点
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
}
}
}
你可以在示例项目中找到其他类,但我想它们并不真正相关。
如你所见,我试图先将视图布局和绘制到位图上。这是因为我只能在
onDraw()
中向画布绘制内容,而不能膨胀视图(我甚至没有一个ViewGroup
来addView()
)。通过使用调试器,我已经发现
initHeader()
中生成的位图只是一块黑色的区域。所以问题可能在于我如何初始化initHeader()
。