自定义透明区域recyclerView

27 阅读1分钟
class EdgeTransRecyclerView : RecyclerView {

  constructor(context: Context) : super(context) {
    init() // 在构造函数中调用init方法
  }

  constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
    init() // 在构造函数中调用init方法
  }

  constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
    context,
    attrs,
    defStyleAttr
  ) {
    init() // 在构造函数中调用init方法
  }


  private var transHeight = 0f
  private var fadeHeight = CommonUtil.dip2px(10f).toFloat()

  private var inDraw = false

  private val path = Path()
  private val rectF = RectF()
  private val clipPath: Path by lazy { Path() }


  private val clipPaint = Paint().apply {
    isAntiAlias = true
    style = Paint.Style.FILL
    xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
  }

  private var fadePaint: Paint? = null

  private fun init() {
    val linearGradient = LinearGradient(
      0f,
      0f,
      0f,
      fadeHeight,
      intArrayOf(CommonUtil.color(R.color.translucent_00_black), Color.BLACK),
      null,
      Shader.TileMode.CLAMP
    )
    fadePaint = Paint()
    fadePaint?.isAntiAlias = true
    fadePaint?.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_IN)
    fadePaint?.shader = linearGradient

  }

  override fun getBottomFadingEdgeStrength(): Float {
    return 0f
  }

  override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
    super.onSizeChanged(w, h, oldw, oldh)
    rectF.set(0F, 0F, w.toFloat(), h.toFloat())
  }

  override fun draw(canvas: Canvas) {
    inDraw = true
    val layerCount = canvas.saveLayer(rectF, null)
    super.draw(canvas)
    canvas.drawRect(0f, 0f, width.toFloat(), getRealTransHeight(), clipPaint)
    canvas.save()
    canvas.translate(0f, getRealTransHeight())
    canvas.drawRect(0f, 0f, width.toFloat(), fadeHeight, fadePaint!!)
    canvas.restore()

    canvas.restoreToCount(layerCount)
    inDraw = false
  }

  private fun getRealTransHeight(): Float {
    if (transHeight > 0) {
      return transHeight.coerceAtMost(height.toFloat() / 2f)
    }
    return 0f
  }


  fun setTransHeight(height: Float) {
    transHeight = height
    invalidate()
  }

  fun getTransHeight(): Float {
    return transHeight
  }

}