RecyclerView详解(二):ItemDecoration使用(kotlin)

我们知道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类。

  1. getItemOffsets() 这个就是就是设置item上下左右的间隔的方法。 可以通过outRect.leftoutRect.topoutRect.rightoutRect.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为第几个,所以可以单独对某一个进行间距的设置。

  1. onDraw() 看到该方法有一个Canvas,就知道它具有绘制的能力。

注:

  • getItemOffsets 是针对每一个 ItemView,而 onDraw 方法却是针对 RecyclerView 本身,所以在 onDraw 方法中需要遍历屏幕上可见的 ItemView,分别获取它们的位置信息,然后分别的绘制对应的分割线。
  • Itemdecoration的onDraw()绘制会先于ItemView的onDraw()绘制
  1. 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

欢迎关注本人公众号和小程序,谢谢
在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/stonezry/article/details/106103078