Как сделать прозрачную (альфа) маску градиента, чтобы один слой стал прозрачным в Android? - PullRequest
0 голосов
/ 27 мая 2018

Я хочу, чтобы один слой исчез под нижними слоями (или прозрачность зависит от того, как вы его видите) в соответствии с градиентом.Так называемая прозрачная (альфа) градиентная маска.Я ищу решение похожее на это , но на Android вместо IOS:

enter image description here

Я пытался эторешение но, как уже упоминалось в комментариях, оверлей не делает слой под прозрачным, он только затухает до указанного цвета.

Есть предложения?

1 Ответ

0 голосов
/ 16 января 2019

Вы можете использовать библиотеку Android-FadingEdgeLayout .Или вот подклассовая структура кадра на основе указанной библиотеки:

public class AlphaGradientLayout extends FrameLayout {

    private static final int DEFAULT_GRADIENT_SIZE_DP = 80;

    public static final int FADE_EDGE_TOP = 1;
    private static final int DIRTY_FLAG_TOP = 1;

    private static final int[] FADE_COLORS = new int[]{Color.TRANSPARENT, Color.BLACK};

    private boolean fadeTop;
    private int gradientSizeTop;
    private Paint gradientPaintTop;
    private Rect gradientRectTop;
    private int gradientDirtyFlags;

    public AlphaGradientLayout(Context context) {
        super(context);
        init(null, 0);
    }

    public AlphaGradientLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs, 0);
    }

    public AlphaGradientLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs, 0);
    }

    private void init(AttributeSet attrs, int defStyleAttr) {
        int defaultSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_GRADIENT_SIZE_DP,
                getResources().getDisplayMetrics());

        if (attrs != null) {
            TypedArray arr = getContext().obtainStyledAttributes(attrs, R.styleable.AlphaGradientLayout, defStyleAttr, 0);
            int flags = arr.getInt(R.styleable.FadingEdgeLayout_fel_edge, 0);

            fadeTop = (flags & FADE_EDGE_TOP) == FADE_EDGE_TOP;

            gradientSizeTop = arr.getDimensionPixelSize(R.styleable.FadingEdgeLayout_fel_size_top, defaultSize);

            if (fadeTop && gradientSizeTop > 0) {
                gradientDirtyFlags |= DIRTY_FLAG_TOP;
            }

            arr.recycle();
        } else {
            gradientSizeTop = defaultSize;
        }

        PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
        gradientPaintTop = new Paint(Paint.ANTI_ALIAS_FLAG);
        gradientPaintTop.setXfermode(mode);

        gradientRectTop = new Rect();
    }

    @Override
    public void setPadding(int left, int top, int right, int bottom) {
        if (getPaddingTop() != top) {
            gradientDirtyFlags |= DIRTY_FLAG_TOP;
        }
        super.setPadding(left, top, right, bottom);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (h != oldh) {
            gradientDirtyFlags |= DIRTY_FLAG_TOP;
        }
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        int newWidth = getWidth(), newHeight = getHeight();
        boolean fadeAnyEdge = fadeTop;
        if (getVisibility() == GONE || newWidth == 0 || newHeight == 0 || !fadeAnyEdge) {
            super.dispatchDraw(canvas);
            return;
        }

        if ((gradientDirtyFlags & DIRTY_FLAG_TOP) == DIRTY_FLAG_TOP) {
            gradientDirtyFlags &= ~DIRTY_FLAG_TOP;

            int actualHeight = getHeight() - getPaddingTop() - getPaddingBottom();
            int size = Math.min(gradientSizeTop, actualHeight);
            int l = getPaddingLeft();
            int t = getPaddingTop();
            int r = getWidth() - getPaddingRight();
            int b = t + size;
            gradientRectTop.set(l, t, r, b);
            LinearGradient gradient = new LinearGradient(l, t, l, b, FADE_COLORS, null, Shader.TileMode.CLAMP);
            gradientPaintTop.setShader(gradient);
        }

        int count = canvas.saveLayer(0.0f, 0.0f, (float) getWidth(), (float) getHeight(), null, Canvas.ALL_SAVE_FLAG);
        super.dispatchDraw(canvas);
        if (fadeTop && gradientSizeTop > 0) {
            canvas.drawRect(gradientRectTop, gradientPaintTop);
        }
        canvas.restoreToCount(count);
    }
} 

Затем переместите элементы, которые вы хотите, исчезнут внутри этого макета

И вот что вы должны получить

...