我可以将 alpha 属性赋予 LinearLayout 但在某些位置,而不是整个视图吗?

Can I give alpha attribute to LinearLayout but in some positions, Not to the whole of view?

我有LinearLayout,我可以给LinearLayoutalpha属性但是在某些位置,不是整个视图吗?

例如给 android:alpha="0.5"LinearLayout,从 150px300px(宽度)和 500px650px(身高)

可能有多种方法可以解决这个问题。我想到的是编写一个自定义可绘制对象,它将按照您想要的方式设置背景。

MyBackgrondDrawable.kt(Kotlin 版本)

class MyBackgroundDrawable : Drawable() {
    private val paint = Paint().apply {
        style = Paint.Style.FILL
        color = 0x0000ff
    }

    private var centerRect = Rect()

    override fun draw(canvas: Canvas) {
        canvas.withSave {
            // Find the center of the canvas.
            val centerWidth = (bounds.width() / 2)
            val centerHeight = (bounds.height() / 2)
            // Define our box around the center.
            centerRect.left = centerWidth - HALF_BOX_SIZE
            centerRect.top = centerHeight - HALF_BOX_SIZE
            centerRect.right = centerWidth + HALF_BOX_SIZE
            centerRect.bottom = centerHeight + HALF_BOX_SIZE
            // Draw the paint with this alpha inside of the center box.
            paint.alpha = 0x55
            withClip(centerRect) {
                drawPaint(paint)
            }
            // Invert the clipped region.
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                clipOutRect(centerRect)
            } else {
                clipRect(centerRect, Region.Op.DIFFERENCE)
            }
            // Draw the paint with this alpha outside of the center box.
            paint.alpha = 0xff
            drawPaint(paint)
        }
    }

    override fun setAlpha(alpha: Int) {
    }

    override fun setColorFilter(colorFilter: ColorFilter?) {
    }

    override fun getOpacity(): Int {
        return PixelFormat.OPAQUE
    }

    private companion object {
        const val BOX_SIZE = 150 // width & height in pixels
        const val HALF_BOX_SIZE = BOX_SIZE / 2

    }
}

MyBackgrondDrawable.java(Java版本)

public class MyBackgroundDrawable extends Drawable {
    private final Paint paint = new Paint();
    private final RectF centerRect = new RectF();

    MyBackgroundDrawableJava() {
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(0x0000ff);
    }


    @Override
    public void draw(Canvas canvas) {
        canvas.save();
        // Find the center of the canvas.
        Rect bounds = getBounds();
        float centerWidth = (bounds.width() / 2f);
        float centerHeight = (bounds.height() / 2f);
        // Define our box around the center.
        centerRect.left = centerWidth - HALF_BOX_SIZE;
        centerRect.top = centerHeight - HALF_BOX_SIZE;
        centerRect.right = centerWidth + HALF_BOX_SIZE;
        centerRect.bottom = centerHeight + HALF_BOX_SIZE;
        // Draw the paint with this alpha inside of the center box.
        paint.setAlpha(0x55);
        canvas.clipRect(centerRect);
        canvas.drawPaint(paint);
        canvas.restore();
        canvas.save();
        // Invert the clipped region.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            canvas.clipOutRect(centerRect);
        } else {
            canvas.clipRect(centerRect, Region.Op.DIFFERENCE);
        }
        // Draw the paint with this alpha outside of the center box.
        paint.setAlpha(0xff);
        canvas.drawPaint(paint);
        canvas.restore();
    }

    @Override
    public void setAlpha(int alpha) {
    }

    @Override
    public void setColorFilter(@Nullable ColorFilter colorFilter) {
    }

    @Override
    public int getOpacity() {
        return PixelFormat.OPAQUE;
    }

    private static final int BOX_SIZE = 150; // width & height in pixels
    private static final int HALF_BOX_SIZE = BOX_SIZE / 2;
}

有了这个可绘制对象,您可以像这样将它设置为布局的背景:

val layout = findViewById<ConstraintLayout>(R.id.layout)
layout.background = MyBackgroundDrawable()

如果您的 minSdk 为 API 24 或更高,您可以按如下方式在可绘制对象文件中定义此可绘制对象:

cutout_with_alpha.xml

<?xml version="1.0" encoding="utf-8"?>
<drawable xmlns:tools="http://schemas.android.com/tools"
    class="com.example.backgroundalpha.MyBackgroundDrawable"
    tools:targetApi="n" />

然后您可以像这样在 XML 中设置背景:

<androidx.constraintlayout.widget.ConstraintLayout
    ...
    android:background="@drawable/cutout_with_alpha">