Android实现圆角按钮的便捷方法

圆角按钮是我们在做界面时常常遇到的UI样式。
通常的办法,是做一个drawable,比如这样:

<?xml version="1.0" encoding="UTF-8"?> 
<shape 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="rectangle"> 
    <!-- 填充的颜色 --> 
    <solid android:color="#ffae00" /> 

    <!-- 圆角的半径 --> 
    <corners android:radius="10dp" /> 
</shape>

在Layout文件里Button的background属性设上这个drawable.xml,就可以了。
然而这样做的话,每次弄个按钮都得新做一个drawable文件,各种drawable多了看着就乱。

是不是可以把color和radius放到Button的属性里去,这样就不用每次再拖一个drawable.xml了是吧?

自定义RoundCornerButton

<widget.RoundCornerButton
    android:id="@+id/btn_commit"
    android:layout_width="100dp"
    android:layout_height="40dp"
    android:gravity="center"
    android:text="我的按钮"
    app:rcb_backgroundColor="@color/yellow"
    app:rcb_backgroundColorDisabled="@color/light_grey"
    app:rcb_cornerRadius="20dp"
    />

如果可以这样在Layout文件里直接设置背景色和圆角半径,是不是很方便!虽然不如drawable灵活,但是已经足以应付设计同学给出的圆角按钮的需求了。

我们就以定义自己的styleable属性开始吧

<declare-styleable name="RoundCornerButton">
    <attr name="rcb_backgroundColor" format="color" />
    <attr name="rcb_backgroundColorDisabled" format="color" />
    <attr name="rcb_cornerRadius" format="dimension" />
</declare-styleable>

从Drawable扩展一个自己的Drawable,很简单

  • 从构造方法传入color和radius,并创建一个实习的画笔;
  • 覆写draw方法,有现成的画圆角矩形的方法可以调用;
  • 暴露一个setRect方法给外边,用于设置绘制区域的宽高。
class RoundCornerDrawable extends Drawable {

    final int color;
    final float radius;
    final Paint paint;
    final RectF rectF;

    RoundCornerDrawable(int color, float radius) {
        this.color = color;
        this.radius = radius;

        // 实心的画笔
        this.paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setAntiAlias(true);
        paint.setColor(color);

        this.rectF = new RectF();
    }

    // 用于设置Drawable宽高
    public void setRect(int width, int height) {
        this.rectF.left = 0;
        this.rectF.top = 0;
        this.rectF.right = width;
        this.rectF.bottom = height;
    }

    @Override
    public void draw(@NonNull Canvas canvas) {
        canvas.drawRoundRect(rectF, radius, radius, paint); // 画圆角矩形,现成的方法
    }

    // 其余方法略
}

定义自己的Button类,有这么几个要点:

  • 与通常的自定义View一样,覆写三个构造方法;
  • 从AttributeSet里读取自定义的属性backgroundColor和cornerRadius,这里暂时忽略backgroundColorDisabled;
  • 每一种状态(例如普通、禁用、按下)是一个RoundCornerDrawable,组合成一个StateListDrawable;
  • onLayout的时候,记得改变每一个RoundCornerDrawable的尺寸。
public class RoundCornerButton extends AppCompatButton {

    private int colorNormal;
    private float cornerRadius;
    private RoundCornerDrawable bgDrawableNormal = null;

    // 省略三个构造方法
    // 构造方法最后一定要调用initCornerBackground完成初始化

    private void initCornerBackground(AttributeSet attrs, int defStyleAttr) {
        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.RoundCornerButton, defStyleAttr, 0);

        this.cornerRadius = a.getDimension(R.styleable.RoundCornerButton_rcb_cornerRadius, 0);
        this.colorNormal = a.getColor(R.styleable.RoundCornerButton_rcb_backgroundColor, 0);
        makeBackgroundDrawable();

        a.recycle();
    }

    private void makeBackgroundDrawable() {
        bgDrawableNormal = new RoundCornerDrawable(this.colorNormal, this.cornerRadius);
        bgDrawableNormal.setRect(getWidth(), getHeight());

        // 设计通常会给出禁用时的样式以及按下时的样式
        // 所以这里用使用StateListDrawable
        StateListDrawable bgDrawable = new StateListDrawable();
        bgDrawable.addState(new int[]{android.R.attr.state_enabled, -android.R.attr.state_pressed}, bgDrawableNormal);
        // 每多一种状态,在这里多加一项
        setBackgroundDrawable(bgDrawable);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);

        // layout之后必然会draw,所以在这里设置drawable的尺寸
        if (bgDrawableNormal != null) {
            bgDrawableNormal.setRect(right - left, bottom - top);
        }
        // 每多一种状态,在这里多加一项
    }
}

附上Demo源代码:https://github.com/realxu/CodeSamples/tree/master/Android/RoundCornerButtonDemo

这就可以啦,我们看看效果:

《Android实现圆角按钮的便捷方法》 round-corner-button-demo.png

    原文作者:贼寇
    原文地址: https://www.jianshu.com/p/bf18a381b032
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞