android自定义渐变色圆角View

先看效果图:

效果图.png

分析这是线性渐变色,圆弧半径刚好是高度的一半,文字居中处理,大小,颜色可调
首先开始自定义控件的基本步骤
1、style自定义属性



    
    
    
    
    
    
    
    
    

注:原本我是想还有点击效果的
2、继承view核心代码

public class MyGradientRoundButton extends View {
private int colorStart;
private int colorEnd;
private int colorPressStart;
private int colorPressEnd;
private int colorS;
private int colorE;
private String text;
private int textColor;
private float textSize;
private float round;
private boolean clickEffect;
private RectF mBackGroundRect;
private LinearGradient backGradient;

//默认画笔
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint mPaintText = new Paint();

public MyGradientRoundButton(Context context, AttributeSet attrs) {
    super(context, attrs);

    //获取自定义属性
    if (attrs != null) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyGradientRoundButton);
        colorStart = typedArray.getColor(R.styleable.MyGradientRoundButton_colorStart, getResources().getColor(R.color.btn_color_start));
        colorEnd = typedArray.getColor(R.styleable.MyGradientRoundButton_colorEnd, getResources().getColor(R.color.btn_color_end));
        round = typedArray.getDimension(R.styleable.MyGradientRoundButton_round, Utils.dip2px(context, 10));
        clickEffect = typedArray.getBoolean(R.styleable.MyGradientRoundButton_clickEffect, false);
        colorPressStart = typedArray.getColor(R.styleable.MyGradientRoundButton_colorPressStart, getResources().getColor(R.color.btn_color_PStart));
        colorPressEnd = typedArray.getColor(R.styleable.MyGradientRoundButton_colorPressEnd, getResources().getColor(R.color.btn_color_PEnd));
        text = typedArray.getString(R.styleable.MyGradientRoundButton_btnText);
        textColor = typedArray.getColor(R.styleable.MyGradientRoundButton_btnTextColor, getResources().getColor(R.color.black));
        textSize = typedArray.getDimension(R.styleable.MyGradientRoundButton_btnTextSize, 16);
        colorS = colorStart;
        colorE = colorEnd;
        typedArray.recycle();
    }
    //必须加,否则onTouchEvent只响应ACTION_DOWN
    setClickable(true);
    //设置抗锯齿
    mPaint.setAntiAlias(true);
    //设置防抖动
    mPaint.setDither(true);
    mPaint.setStyle(Paint.Style.FILL);

    mPaintText.setAntiAlias(true);
    mPaintText.setDither(true);
}


@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    mBackGroundRect = new RectF(0, 0, w, h);
    backGradient = new LinearGradient(0, 0, w, 0, new int[]{colorS, colorE}, null, Shader.TileMode.CLAMP);
}


@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    mPaint.setShader(backGradient);
    //绘制背景 圆角矩形
    if (mBackGroundRect != null) {
        canvas.drawRoundRect(mBackGroundRect, round, round, mPaint);
    }
    //绘制文字
    mPaintText.setTextSize(textSize);
    mPaintText.setColor(textColor);
    mPaintText.setTextAlign(Paint.Align.CENTER);
    Paint.FontMetricsInt fontMetrics = mPaintText.getFontMetricsInt();
    float baseline = mBackGroundRect.top + (mBackGroundRect.bottom - mBackGroundRect.top - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top;
    canvas.drawText(text, canvas.getWidth() / 2, baseline, mPaintText);

}

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (clickEffect) {
        //刷新
        invalidate();
        //判断点击操作
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                colorS = colorPressStart;
                colorE = colorPressEnd;
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_UP:
                colorS = colorStart;
                colorE = colorEnd;
                break;
            case MotionEvent.ACTION_CANCEL:
                break;
        }
    }

    return super.onTouchEvent(event);
}


public void setText(String text) {
    if (!TextUtils.isEmpty(text)) {
        this.text = text;
        invalidate();
    }
}}

关键代码讲解:
onDraw():绘制图形过程,canvas.drawXXX()就是在绘制一层层图层,所以drawRoundRect要在drawText之前
LinearGradient:线性渐变色
RectF:正方形,配合drawRoundRect就可以画出带圆角的图形
onSizeChanged():发生在onDraw()之前,一般可以做些不变的参数设定,调用onDraw(),它也不调用的
invalidate():每调一次,也就调用了一次onDraw()方法,这样就可以做点击效果了

3、引用列子


这个自定义控件有个缺陷宽高不能用wrap_content属性。

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注