android多点渐变背景(边框)实现

import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;

import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

public class GradientBorderDrawable extends Drawable {
    private int[] mColors = null;
    private float[] mPositions = null;
    private float mCornerRadius = 0f;
    private int mAlpha = 0xFF;
    private boolean mIsLeftTopCornerRound = true;
    private boolean mIsRightTopCornerRound = true;
    private boolean mIsRightBottomCornerRound = true;
    private boolean mIsLeftBottomCornerRound = true;
    private float[] mCornerRadii = null;
    private Orientation mOrientation = Orientation.TOP_BOTTOM;
    private boolean mPathIsDirty = true;
    private boolean mGradientIsDirty = true;
    private RectF mRect = new RectF();
    private Path mPath = new Path();
    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    @Override
    public void draw(@NonNull Canvas canvas) {
        if (mAlpha <= 0) {
            return;
        }
        int[] drawColors = mColors;
        if (!ensureValidRect(drawColors)) {
            return;
        }
        mPaint.setAlpha(mAlpha);
        updateRound();
        if (mCornerRadii != null) {
            buildPathIfDirty(drawColors);
            canvas.drawPath(mPath, mPaint);
        } else {
            canvas.drawRect(mRect, mPaint);
        }
    }

    @Override
    public void setAlpha(int alpha) {
        if (alpha != mAlpha) {
            mAlpha = alpha;
            invalidateSelf();
        }
    }

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

    }

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

    private boolean ensureValidRect(int[] colors) {
        if (mGradientIsDirty) {
            mGradientIsDirty = false;
            mRect.set(getBounds());
            if (colors != null) {
                RectF r = mRect;
                float x0;
                float x1;
                float y0;
                float y1;
                switch (mOrientation) {
                    case RIGHT_LEFT:
                        x0 = r.right;
                        y0 = r.top;
                        x1 = r.left;
                        y1 = y0;
                        break;
                    case BOTTOM_TOP:
                        x0 = r.left;
                        y0 = r.bottom;
                        x1 = x0;
                        y1 = r.top;
                        break;
                    case LEFT_RIGHT:
                        x0 = r.left;
                        y0 = r.top;
                        x1 = r.right;
                        y1 = y0;
                        break;
                    case LT_BR:
                        x0 = r.left;
                        y0 = r.top;
                        x1 = r.right;
                        y1 = r.bottom;
                        break;
                    default:
                        x0 = r.left;
                        y0 = r.top;
                        x1 = x0;
                        y1 = r.bottom;
                        break;
                }
                mPaint.setShader(new LinearGradient(
                        x0, y0, x1, y1,
                        colors, mPositions, Shader.TileMode.CLAMP
                ));
            }
        }
        return !mRect.isEmpty();
    }

    private void updateRound() {
        if (mCornerRadius <= 0) {
            mCornerRadii = null;
            return;
        }
        if (mCornerRadii == null) {
            mCornerRadii = new float[8];
        }
        if (mIsLeftTopCornerRound) {
            mCornerRadii[0] = mCornerRadius;
        } else {
            mCornerRadii[0] = 0;
        }
        if (mIsLeftTopCornerRound) {
            mCornerRadii[1] = mCornerRadius;
        } else {
            mCornerRadii[1] = 0;
        }
        if (mIsRightTopCornerRound) {
            mCornerRadii[2] = mCornerRadius;
        } else {
            mCornerRadii[2] = 0;
        }
        if (mIsRightTopCornerRound) {
            mCornerRadii[3] = mCornerRadius;
        } else {
            mCornerRadii[3] = 0;
        }
        if (mIsRightBottomCornerRound) {
            mCornerRadii[4] = mCornerRadius;
        } else {
            mCornerRadii[4] = 0;
        }
        if (mIsRightBottomCornerRound) {
            mCornerRadii[5] = mCornerRadius;
        } else {
            mCornerRadii[5] = 0;
        }
        if (mIsLeftBottomCornerRound) {
            mCornerRadii[6] = mCornerRadius;
        } else {
            mCornerRadii[6] = 0;
        }
        if (mIsLeftBottomCornerRound) {
            mCornerRadii[7] = mCornerRadius;
        } else {
            mCornerRadii[7] = 0;
        }
    }

    private void buildPathIfDirty(int[] colors) {
        if (mPathIsDirty) {
            ensureValidRect(colors);
            mPath.reset();
            if (mCornerRadii != null) {
                mPath.addRoundRect(mRect, mCornerRadii, Path.Direction.CW);
            }
            mPathIsDirty = false;
        }
    }

    public void setColor(@ColorInt int color) {
        mPaint.setColor(color);
        mGradientIsDirty = true;
        invalidateSelf();
    }

    public void setColors(@ColorInt int[] colors) {
        setColors(colors, null);
    }

    public void setColors(@ColorInt int[] colors, float[] offset) {
        mGradientIsDirty = true;
        mPositions = offset; //需要重新计算mPositions
        mColors = colors;
        invalidateSelf();
    }

    public void setOrientation(Orientation value) {
        if (mOrientation == value) {
            return;
        }
        mGradientIsDirty = true;
        mOrientation = value;
        invalidateSelf();
    }

    public void setCornerRadius(float cornerRadius) {
        if (mCornerRadius != cornerRadius) {
            mPathIsDirty = true;
            mCornerRadius = cornerRadius;
            invalidateSelf();
        }
    }

    public void setRoundCorner(boolean lt, boolean rt, boolean rb, boolean lb) {
        mPathIsDirty = true;
        mIsLeftTopCornerRound = lt;
        mIsRightTopCornerRound = rt;
        mIsRightBottomCornerRound = rb;
        mIsLeftBottomCornerRound = lb;
        if (mCornerRadius <= 0 && (mIsLeftTopCornerRound || mIsRightTopCornerRound || mIsRightBottomCornerRound
                    || mIsLeftBottomCornerRound)
        ) {
            mCornerRadius = 9f;
        }
        invalidateSelf();
    }

    //设置后将只显示边框
    public void setStrokeWidth(float strokeWidth) {
        if (strokeWidth == mPaint.getStrokeWidth()) {
            return;
        }
        if (strokeWidth > 0) {
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(strokeWidth);
        } else {
            mPaint.setStyle(Paint.Style.FILL);
            mPaint.setStrokeWidth(0f);
        }
        mGradientIsDirty = true;
    }

    public void setAntiAlias(boolean alias) {
        mPaint.setAntiAlias(alias);
        invalidateSelf();
    }

    @Override
    public void setDither(boolean dither) {
        mPaint.setDither(dither);
        invalidateSelf();
    }

    enum Orientation {
        TOP_BOTTOM,

        RIGHT_LEFT,
     
        BOTTOM_TOP,
        
        LEFT_RIGHT,
     
        LT_BR
    }
}

使用:

        int[] colors = {getResources().getColor(R.color.blue),
                getResources().getColor(R.color.green),
                getResources().getColor(R.color.read),
                getResources().getColor(R.color.gold),
                getResources().getColor(R.color.purple)};
        float[] offset = {0f, 0.2f, 0.5f, 0.9f, 1f};
        GradientBorderDrawable drawable = new GradientBorderDrawable();
        drawable.setColors(colors, offset);
//        drawable.setStrokeWidth(6);//设置后将只显示边框
        drawable.setCornerRadius(9);
//        drawable.setAlpha(100);
        drawable.setOrientation(GradientBorderDrawable.Orientation.TOP_BOTTOM);
        findViewById(R.id.background).setBackground(drawable);

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值