有没有一种方法可以将视图融合到其下方?

时间:2019-09-09 15:53:31

标签: android android-layout kotlin

我正在以编程方式生成一个大图像,该图像在某些区域具有纯白色填充,而在其他区域则完全透明。我希望能够用单色突出显示图像的一部分。我能想到的最简单的方法是在ImageView的顶部放置另一个View,并使它的背景变为纯色。然后,我想使用Porter Duff Xfer模式将视图的背景色乘到图像上。从数学上讲,这会将视图的颜色仅应用于白色填充区域,而其他区域将保持完全透明。

有没有办法做到这一点?我已经尝试过以下方法,方法是创建一个视图以使用设置了xfer模式的绘画进行绘制。

class FilterView : View {

    private val paint = Paint().apply {
        isAntiAlias = true
        style = Paint.Style.FILL
        alpha = 0xFF
        xfermode = PorterDuffXfermode(PorterDuff.Mode.MULTIPLY)
    }

    var filterColor: Int
        get() = paint.color
        set(value) {
            paint.color = value
            invalidate()
        }


    constructor(context: Context) : this(context, null, 0)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int)
            : this(context, attrs, defStyleAttr, 0)

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int)
            : super(context, attrs, defStyleAttr, defStyleRes) {
        val typedArray = context
            .obtainStyledAttributes(attrs, R.styleable.FilterView, defStyleAttr, defStyleRes)
        try {
            paint.color = typedArray.getColor(R.styleable.FilterView_filterColor, Color.WHITE)
        }
        finally {
            typedArray.recycle()
        }
    }

    private val bounds = Rect()
    override fun onDraw(canvas: Canvas) {
        canvas.getClipBounds(bounds)
        canvas.drawRect(bounds.left.toFloat(),
                        bounds.top.toFloat(),
                        bounds.right.toFloat(),
                        bounds.bottom.toFloat(),
                        paint)
    }
}

当前使用这种方法,应用xfer模式会导致视图的颜色完全变为黑色,这使我相信Canvas可能不会从堆栈中的其他视图获得源颜色数据。

我还尝试在过滤器视图中使用以下内容:

    ...
    private val layerPaint = Paint().apply {
        alpha = 0xFF
        colorFilter = null
        xfermode = PorterDuffXfermode(PorterDuff.Mode.MULTIPLY)
    }

    constructor(...):super(...) {
        ...
        setLayerPaint(layerPaint)
        setLayerType(LAYER_TYPE_SOFTWARE, layerPaint)
    }

但这会导致整个叠加视图消失。

0 个答案:

没有答案