Затухающий верхний край RecyclerView

В моем макете у меня есть ImageView и RecyclerView,RecyclerView перекрывает ImageView выше этого на 128dp, и имеет 128dp paddingTop чтобы при прокрутке дочерний элемент перекрывал изображение.

Я бы хотел, чтобы верхний край RecyclerView исчез с помощью градиента, чтобы получить эффект, аналогичный эффекту, производимому requiresFadingEdge="vertical", Вот что у меня есть и что я хочу рядом:

Актуальный макет Желаемый макет

Что я пробовал до сих пор:

  1. Подкласс RecyclerView переопределить dispatchDrawгде я использую PorterDuffXfermode (DST_IN), чтобы исчезнуть верхний край представления. Это не работает, так как результат похож на первое изображение.

    private val fadingEdgeRect = Rect()
    private val fadingEdgePaint = Paint().apply {
        xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_IN)
    }
    
    [...]
    
    override fun dispatchDraw(canvas: Canvas) {
        if (visibility == View.GONE || edgeLength == 0) {
            super.dispatchDraw(canvas)
            return
        }
    
        val count = canvas.saveLayer(viewBounds, null, Canvas.ALL_SAVE_FLAG)
        super.dispatchDraw(canvas)
        canvas.drawRect(fadingEdgeRect, fadingEdgePaint)
        canvas.restoreToCount(count)
    }
    
    // This is called at initialization, in onSizeChanged 
    // and whenever edgeLength changes.
    private fun configureEdge(@Px length: Int) {
        if (length == 0) {
            fadingEdgeRect.setEmpty()
            fadingEdgePaint.shader = null
        } else {
           val actualHeight = paddingTop + height + paddingBottom
           val size = minOf(length, actualHeight)
    
           val left = ViewCompat.getPaddingStart(this)
           val top = 0
           val right = ViewCompat.getPaddingEnd(this)
           val bottom = top + size
    
           fadingEdgeRect.set(left, top, right, bottom)
           fadingEdgePaint.shader = LinearGradient(
                    left.toFloat(),
                    top.toFloat(),
                    right.toFloat(),
                    bottom.toFloat(),
                    Color.TRANSPARENT, Color.WHITE,
                    Shader.TileMode.CLAMP
            )
        }
    }
    
  2. Настройте аппаратный уровень с setLayerType(LAYER_TYPE_HARDWARE, fadingEdgePaint), Я не знаю, как это работает, но я читал, что это более эффективно, чем canvas.saveLayer особенно для моего случая использования.

Может ли кто-нибудь дать мне несколько советов о том, как улучшить мой FadingEdgeRecyclerView заставить эффект затухания работать или объяснить мне, как использовать аппаратные слои для того же?

Заранее спасибо!

0 ответов

Другие вопросы по тегам