RecyclerView基础篇-ItemDecoration

2020-08-31  本文已影响0人  dashingqi
Android_Banner.jpg

简介

使用

实现分割线效果
实现过程
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
   //新增了一个背景色
    android:background="#f4f4f4"
    tools:context=".GridLayoutManagerActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
  <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    // 新增背景色
    android:background="#ffffff"
    android:padding="16dp">

    <ImageView
        android:id="@+id/ivCover"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:scaleType="centerCrop"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tvName"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="4dp"
        android:ellipsize="end"
        android:maxLines="1"
        android:textColor="#333333"
        android:textSize="18sp"
        app:layout_constraintLeft_toRightOf="@+id/ivCover"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="@+id/ivCover" />


    <TextView
        android:id="@+id/tvDesc"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="8dp"
        android:textSize="14sp"
        app:layout_constraintBottom_toBottomOf="@+id/ivCover"
        app:layout_constraintLeft_toRightOf="@+id/ivCover"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tvName"
        tools:text="测试测试测试测试" />

</androidx.constraintlayout.widget.ConstraintLayout>
  class ComItemDecorate : RecyclerView.ItemDecoration() {

    /**
     * view:指代着每一个Item
     * outRect 是一个为0的Rect,填充在Item的四周
     */
    override fun getItemOffsets(
        outRect: Rect,
        view: View,
        parent: RecyclerView,
        state: RecyclerView.State
    ) {
        // 让item的rect的底部 高度设置为16f
        outRect.bottom = DensityUtils.dip2pxInt(parent.context, 16f)

    }

    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)
    }
}
    var adapter = GridLayoutAdapter(items)
        rv.addItemDecoration(ComItemDecorate())
        rv.adapter = adapter
总结
ItemDecoration.onDraw()
override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        super.onDraw(c, parent, state)
        // item数
        val childItemCount = parent.childCount

        for (index in 0..childItemCount-1) {
            val itemView = parent.getChildAt(index)
            val top = itemView.top
            val left = parent.paddingLeft
            val right = parent.paddingRight
            val bottom = itemView.top + DensityUtils.dip2pxInt(parent.context, 16f)
            val rect = Rect(top, left, right, bottom)
            c.drawRect(rect, drawPaint)
        }
    }
getItemOffset()配合onDraw()方法实现时间轴
class TimelineItemDecoration : RecyclerView.ItemDecoration() {

    private val paint: Paint = Paint()

    private val offset = 120

    init {
        //设置画笔
        paint.isAntiAlias = true
        paint.style = Paint.Style.FILL_AND_STROKE
        paint.color = Color.RED
    }


    override fun getItemOffsets(
        outRect: Rect,
        view: View,
        parent: RecyclerView,
        state: RecyclerView.State
    ) {

        val position = parent.getChildAdapterPosition(view)
        //当是第一条数据的时候,不设置outRect的顶部
        val topOffset = offset
        if (position != 0) {
            outRect.top = topOffset
        }

        outRect.left = offset
    }

    override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {

        // 条目个数
        val childItemCount = parent.childCount
        for (position in 0 until childItemCount) {
            // 对应的ItemView
            val itemView = parent.getChildAt(position)

            val index = parent.getChildAdapterPosition(itemView)

            // 第一个条目 没有做outRect的top拉伸
            var dividerTop = itemView.top - offset
            if (index == 0) {
                dividerTop = itemView.top
            }

            val dividerBottom = itemView.bottom

            val dividerLeft = parent.paddingLeft

            val dividerRight = parent.width - parent.paddingRight
            //画中心圆

            val radiusX = dividerLeft + offset / 2

            val radiusY = (dividerBottom - dividerTop) / 2 + dividerTop

            c.drawCircle(radiusX.toFloat(), radiusY.toFloat(), radiusX / 2f, paint)

            // 画第一条直线

            val oneLineStartX = dividerLeft + radiusX

            val oneLineStartY = dividerTop

            val oneLineEndX = dividerLeft + radiusX

            val oneLineEndY = dividerTop + (dividerBottom - dividerTop) / 2 - radiusX / 2

            c.drawLine(
                oneLineStartX.toFloat(), oneLineStartY.toFloat(),
                oneLineEndX.toFloat(), oneLineEndY.toFloat(), paint
            )

            // 画第二条直线

            val twoLineStartX = dividerLeft + radiusX
            val twoLineStartY = (dividerBottom - dividerTop) / 2  + dividerTop
            val twoLineEndX = dividerLeft + radiusX
            val twoLineEndY = dividerBottom

            c.drawLine(
                twoLineStartX.toFloat(),
                twoLineStartY.toFloat(), twoLineEndX.toFloat(), twoLineEndY.toFloat(), paint
            )
        }

    }
}
onDrawOver()
上一篇 下一篇

猜你喜欢

热点阅读