RecyclerView详解(二):ItemDecoration使用(kotlin)
16lz
2021-01-23
我们知道listview可以通过在布局文件中设置
android:divider=”#ffff0000” android:dividerHeight=”10dp”
来控制item之间的间隔和颜色,但是recyclerview是不行的。 recyclerview提供了一个ItemDecoration类供开发者扩展使用,再通过RecyclerView.addItemDecoration(ItemDecoration)
的方法,即可以完成对item间间隔的定义。其实ItemDecoration相当于可以自定义item边缘样式的一个类。下面我们就来介绍它。
这里主要关注ItemDecoration的三个方法
class MyDecoration : RecyclerView.ItemDecoration() { override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) { super.onDraw(c, parent, state) } override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) { super.onDrawOver(c, parent, state) } override fun getItemOffsets( outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State ) { super.getItemOffsets(outRect, view, parent, state) } }
我们这里自定义一个MyDecoration,继承了RecyclerView.ItemDecoration类。
- getItemOffsets() 这个就是就是设置item上下左右的间隔的方法。 可以通过
outRect.left
,outRect.top
,outRect.right
,outRect.bottoom
的方法分别设置item上下左右的间距。如下图
比如我这边设置bottom的间距为10dp,可以这样设置
override fun getItemOffsets( outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State ) { super.getItemOffsets(outRect, view, parent, state) outRect.bottom = DensityUtils.dp_px(this@LinearManagerActivity, 10f) }
效果图
其他方向的间隔一样,这边就不在叙述。另外这个可以通过 parent.getChildAdapterPosition(view)的方法判断item为第几个,所以可以单独对某一个进行间距的设置。
- onDraw() 看到该方法有一个Canvas,就知道它具有绘制的能力。
注:
- getItemOffsets 是针对每一个 ItemView,而 onDraw 方法却是针对 RecyclerView 本身,所以在 onDraw 方法中需要遍历屏幕上可见的 ItemView,分别获取它们的位置信息,然后分别的绘制对应的分割线。
- Itemdecoration的onDraw()绘制会先于ItemView的onDraw()绘制
- onDrawOver() 与onDraw()方法类似,只是它会绘制在itemview和Itemdecoration之上。通常可以用来绘制悬浮的组件。 比如可以在每个itemview左上角绘制一个图标。 关于上面两者方式用法,请参见下面的代码。代码很简单,这边就不多叙述了。
/** * 绘制间隔 */ internal inner class MyItemDecoration( context: Context, private val orientation: Int ) : RecyclerView.ItemDecoration() { private val mLine: Drawable? private val bitmap: Bitmap private val mPaint: Paint override fun onDraw( c: Canvas, parent: RecyclerView, state: RecyclerView.State ) { super.onDraw(c, parent, state) if (orientation == RecyclerView.HORIZONTAL) { drawVertical(c, parent, state) } else if (orientation == RecyclerView.VERTICAL) { drawHorizontal(c, parent, state) } } override fun onDrawOver( c: Canvas, parent: RecyclerView, state: RecyclerView.State ) { super.onDrawOver(c, parent, state) val childCount: Int = parent.getChildCount() for (i in 0 until childCount) { val child: View = parent.getChildAt(i) val left = child.left val top = child.top c.drawBitmap(bitmap, left.toFloat(), top.toFloat(), mPaint) } } override fun getItemOffsets( outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State ) { super.getItemOffsets(outRect, view, parent, state) if (orientation == RecyclerView.HORIZONTAL) { //画垂直线 outRect[0, 0, mLine!!.intrinsicWidth] = 0 } else if (orientation == RecyclerView.VERTICAL) { //画水平线 outRect[0, 0, 0] = mLine!!.intrinsicHeight } } /** * 画垂直分割线 */ private fun drawVertical( c: Canvas, parent: RecyclerView, state: RecyclerView.State ) { val childCount: Int = parent.getChildCount() for (i in 0 until childCount) { val child: View = parent.getChildAt(i) val left = child.right val top = child.top val right = left + mLine!!.intrinsicWidth val bottom = child.bottom mLine.setBounds(left, top, right, bottom) mLine.draw(c) } } /** * 画水平分割线 */ private fun drawHorizontal( c: Canvas, parent: RecyclerView, state: RecyclerView.State ) { val childCount: Int = parent.getChildCount() for (i in 0 until childCount) { val child: View = parent.getChildAt(i) val left = child.left val top = child.bottom val right = child.right val bottom = top + mLine!!.intrinsicHeight mLine.setBounds(left, top, right, bottom) mLine.draw(c) } } init { val attrs = intArrayOf(android.R.attr.listDivider) val a = context.obtainStyledAttributes(attrs) mLine = a.getDrawable(0) a.recycle() mPaint = Paint() bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher) } }
效果图
git地址:https://gitee.com/stonezry/AndroidDemo
欢迎关注本人公众号和小程序,谢谢
更多相关文章
- unity在android显示界面(UnityPlayerActivity)不重复加载且app退出
- Android 使用selector改变按钮状态实例详解
- ListView自动滚动方法
- android投屏和媒体共享相关 && audio focus机制相关 && AudioTra
- Android中的Logcat方法查看内核的日志
- 关于Android方法数量限制的问题
- Android第三方登录-----微信登录接入方法