Sir*_*Lam 3 android android-recyclerview item-decoration
我已经知道如何画一个东西ItemDecoration,但现在我想画View一个ItemDecoration.
由于设置有点复杂,我创建了一个可以重现问题的示例项目.
我有RecyclerView20个项目,只显示数字.我想在第5项上面添加一个带有"This is Number 5"字样的黑色标题.
当然,这是我真正问题的简化版本,在我真正的问题中我必须通过ItemDecoration来做到这一点,所以请不要给出不使用ItemDecoration的替代方案.
如下面的截图所示,装饰的大小正确,android:background="@color/black"可以绘制xml的第一层(有); 但不包括TextView应该显示"This is Number 5" 的子视图.
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
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在示例项目中找到其他类.但我猜他们并没有真正相关.
如您所见,我正在尝试布局并首先将视图绘制到位图.这是因为我只能在画布中绘制一些东西onDraw()而不是给视图充气(我甚ViewGroup至没有去过addView()).
通过使用调试器,我已经可以看到生成的位图initHeader()只是一块黑色.所以问题可能在于我 initHeader().
想出来(哎呀我的赏金)
为了View正确创建a ,需要3个步骤:
view.measure())view.layout())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
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,widthSpec和heightSpec将根据您的使用情况而有所不同.那是另一个话题,所以我不在这里解释.
| 归档时间: |
|
| 查看次数: |
1062 次 |
| 最近记录: |