Как можно оформить круговой элемент для RecyclerView?

У меня есть recyclerView. Я хочу использовать декорацию круговой черты, которую я могу реализовать с помощью тире, но у меня не может быть декораторов круга? Мне интересно, есть ли PathEffect, но с кругом или как я могу это реализовать? введите описание изображения здесь

class SeparatorDecoration(context: Context, @ColorInt color: Int,
                          @FloatRange(from = 0.0, fromInclusive = false) heightDp: Float) : RecyclerView.ItemDecoration() {

  private val mPaint: Paint

  init {
    mPaint = Paint()
    mPaint.color = color

    mPaint.strokeWidth = 5f
    mPaint.color = Color.RED
    mPaint.isAntiAlias = true
    val interval = floatArrayOf(25.0f, 25.0f)
    mPaint.pathEffect = DashPathEffect(interval, 2.5f)
  }

  override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
    val params = view.layoutParams as RecyclerView.LayoutParams
    val position = params.viewAdapterPosition
    if (position < state.itemCount) {
      outRect.set(0, 0, 0, 4) // left, top, right, bottom
    } else {
      outRect.setEmpty() // 0, 0, 0, 0
    }
  }

  override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
    val offset = 2
    for (i in 0 until parent.childCount) {
      // get the view
      val view = parent.getChildAt(i)
      val params = view.layoutParams as RecyclerView.LayoutParams
      val position = params.viewAdapterPosition
      if (position < state.itemCount) {
        c.drawLine(view.left.toFloat(), (view.bottom + offset).toFloat(), view.right.toFloat(), (view.bottom + offset).toFloat(), mPaint)
      }
    }
  }
}

1 ответ

Прежде всего, я не смог добиться DashPathEffect с помощью canvas.drawLine(), поэтому вместо этого я использую canvas.drawPath(), надеюсь, это нормально.

Вероятно, вы не смогли бы нарисовать идеальный эффект контура, поскольку Paint не поддерживает круговой ход. Краска поддерживает только тип колпачка: BUTT, ROUND и SHAPE.

Штрих проецируется полукругом с центром в конце пути.

Тем не менее, вы можете взломать для достижения близкого результата:

  • Рисование с помощью 2 объектов Paint, которые имеют setStrokeCap ​​(Paint.Cap.ROUND) и setStrokeCap ​​(Paint.Cap.ROUND).
  • Нарисуйте оба объекта Paint, один над другим, с помощью DashedLineEffect.

    init {
    //Prepare 2 paints objects...
    mPaint1 = Paint()
    mPaint1.setColor(Color.BLUE)
    mPaint1.setStrokeWidth(50f)
    mPaint1.setStyle(Paint.Style.STROKE)
    mPaint1.setAntiAlias(true)
    mPaint1.setStrokeCap(Paint.Cap.ROUND)
    mPaint1.setStrokeJoin(Paint.Join.ROUND)
    
    mPaint2 = Paint()
    mPaint2.setColor(Color.GREEN)
    mPaint2.setStrokeWidth(50f)
    mPaint2.setStyle(Paint.Style.STROKE)
    mPaint2.setAntiAlias(true)
    mPaint2.setStrokeCap(Paint.Cap.ROUND)
    
    val interval = floatArrayOf(25.0f, 25.0f)
    mPaint1.pathEffect = DashPathEffect(interval, 2.5f)
    mPaint2.pathEffect = DashPathEffect(interval, 2.5f)
    }
    
    override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
    ...
    
    mPath1.moveTo(view.left.toFloat(),view.bottom.toFloat() - 5.0f)
    mPath1.lineTo(view.right.toFloat(),view.bottom.toFloat()- 5.0f)
    mPath2.moveTo(view.left.toFloat(),view.bottom.toFloat())
    mPath2.lineTo(view.right.toFloat(),view.bottom.toFloat())
    ....
    // then draw them both
    canvas.drawPath(mPath1,mPaint1)
    canvas.drawPath(mPath2,mPaint2)
    
Другие вопросы по тегам