Android 按钮设置圆角,自定义圆角按钮

在res目录下的drawable目录下新建shape.xml或者selector文件

1.定义一个圆角shape

//btn_bg_normal.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@color/color_f24c23" />
    <stroke
        android:width="1dp"
        android:color="@android:color/transparent" />
    <corners android:radius="10dp" />
shape>

使用定义的btn_bg_normal

<Button android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/submit_apply"
        android:background="@drawable/btn_bg_normal"/>

2.定义一个selector

//btn_bg_selector.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/btn_bg_enabled_false" android:state_enabled="false" />
    <item android:drawable="@drawable/btn_bg_pressed" android:state_pressed="true" />
    <item android:drawable="@drawable/btn_bg_normal" />
selector>

使用方法和上面一样,定义了三种状态

  • 不可用状态:
  • 点击的效果状态:
  • 常态:

note: btn_bg_enabled_false,btn_bg_pressed,btn_bg_normal几个资源主要是颜色不同,按照ui要求设置就行

上面是使用圆角按钮的常用做法,如果有几个按钮的颜色效果或者圆角大小不同怎么办?拷贝一份重新定义呗,一个还好说,给你来5,6个你受得鸟不,受不鸟就干脆造个轮子

自定义可以设置圆角效果的按钮控件

1.申明一些自定义圆角按钮中需要用到的属性

//在values文件夹下的attrs.xml文件中
    <declare-styleable name="radiusCornersButton">
        <attr name="background_normal_color" format="reference|color" />
        <attr name="background_pressed_color" format="reference|color" />
        <attr name="background_enable_false_color" format="reference|color" />
        <attr name="background_stroke_color" format="reference|color" />
        <attr name="background_radius" format="reference|dimension" />
        <attr name="background_topLeftRadius" format="reference|dimension" />
        <attr name="background_topRightRadius" format="reference|dimension" />
        <attr name="background_bottomRightRadius" format="reference|dimension" />
        <attr name="background_bottomLeftRadius" format="reference|dimension" />
        <attr name="background_stroke_width" format="reference|dimension" />
    declare-styleable>

属性说明:

属性 说明 对应之前的xml
background_normal_color 初始颜色 selector 中的最后一个item ,什么状态都不设置
background_pressed_color 按压时颜色 selector 中的android:state_pressed=“true”
background_enable_false_color 不可用时颜色 selector 中的android:state_enabled=“false”
上面三个颜色对应 shape 中的 >
background_stroke_color 边框颜色 对应 shape 中的
background_radius 圆角大小,四个角 对应 shape 中的
background_topLeftRadius top-left圆角大小,会覆盖background_radius效果 对应 shape 中的
background_topRightRadius top-right圆角大小,会覆盖background_radius效果 对应 shape 中的
background_bottomRightRadius bottom-right圆角大小,会覆盖background_radius效果 对应 shape 中的
background_bottomLeftRadius bottom-left圆角大小,会覆盖background_radius效果 对应 shape 中的
background_stroke_width 边框大小 对应 shape 中的

2.撸自定义圆角按钮RadiusCornersButton代码

public class RadiusCornersButton extends android.support.v7.widget.AppCompatButton {
    public RadiusCornersButton(Context context) {
        super(context);
    }
    public RadiusCornersButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(attrs);
    }
    public RadiusCornersButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(attrs);
    }
    /**
     * 颜色值不要设置默认值为-1;
     * TypedArray的getColor方法在颜色设置为白色的时候返回-1
     * why:白色的16进制 #FFFFFF, 不设置不透明度默认FF ,ARGB合起来 #FFFFFFFF,这个不就是整数-1
     */
    private int backgroundNormalColor = -2;
    private int backgroundPressedColor = -2;
    private int backgroundEnableFalseColor = -2;
    private int backgroundStrokeColor = -2;
    private int backgroundRadius = -1;
    private int backgroundTopLeftRadius = -1;
    private int backgroundTopRightRadius = -1;
    private int backgroundBottomLeftRadius = -1;
    private int backgroundBottomRightRadius = -1;
    private int backgroundStrokeWidth = -1;
    private static final int[] STATE_NORMAL = {-android.R.attr.state_pressed, android.R.attr.state_enabled};
    private static final int[] STATE_PRESSED = {android.R.attr.state_pressed};
    private static final int[] STATE_ENABLE_FALSE = {-android.R.attr.state_enabled};
    private boolean isNotSetColor() {
        return backgroundNormalColor == -2
                && backgroundPressedColor == -2
                && backgroundEnableFalseColor == -2;
    }
    private boolean isNotSetRadius() {
        return backgroundRadius == -1
                && backgroundTopLeftRadius == -1
                && backgroundTopRightRadius == -1
                && backgroundBottomLeftRadius == -1
                && backgroundBottomRightRadius == -1;
    }
    private boolean isNotSetSeparatelyRadius() {
        return backgroundTopLeftRadius == -1
                && backgroundTopRightRadius == -1
                && backgroundBottomLeftRadius == -1
                && backgroundBottomRightRadius == -1;
    }
    /**
     * 设置四个角的圆角效果
     */
    private void setRadius(GradientDrawable gradientDrawable) {
        if (isNotSetSeparatelyRadius()) return;
        float[] radii = new float[8];
        //top-left
        radii[0] = backgroundTopLeftRadius;
        radii[1] = backgroundTopLeftRadius;
        //top-right
        radii[2] = backgroundTopRightRadius;
        radii[3] = backgroundTopRightRadius;
        //bottom-right
        radii[4] = backgroundBottomLeftRadius;
        radii[5] = backgroundBottomLeftRadius;
        //bottom-left
        radii[6] = backgroundBottomRightRadius;
        radii[7] = backgroundBottomRightRadius;
        gradientDrawable.setCornerRadii(radii);
    }
    private void initView(AttributeSet attrs) {
        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.radiusCornersButton, 0, 0);
        try {
            backgroundNormalColor = a.getColor(R.styleable.radiusCornersButton_background_normal_color, -2);
            backgroundPressedColor = a.getColor(R.styleable.radiusCornersButton_background_pressed_color, -2);
            backgroundEnableFalseColor = a.getColor(R.styleable.radiusCornersButton_background_enable_false_color, -2);
            backgroundStrokeColor = a.getColor(R.styleable.radiusCornersButton_background_stroke_color, -2);
            backgroundRadius = a.getLayoutDimension(R.styleable.radiusCornersButton_background_radius, -1);
            backgroundTopLeftRadius = a.getLayoutDimension(R.styleable.radiusCornersButton_background_topLeftRadius, -1);
            backgroundTopRightRadius = a.getLayoutDimension(R.styleable.radiusCornersButton_background_topRightRadius, -1);
            backgroundBottomLeftRadius = a.getLayoutDimension(R.styleable.radiusCornersButton_background_bottomLeftRadius, -1);
            backgroundBottomRightRadius = a.getLayoutDimension(R.styleable.radiusCornersButton_background_bottomRightRadius, -1);
            backgroundStrokeWidth = a.getLayoutDimension(R.styleable.radiusCornersButton_background_stroke_width, -1);
        } finally {
            a.recycle();
        }
        if (isNotSetColor() || isNotSetRadius()) return;
        StateListDrawable stateListDrawable = new StateListDrawable();
        //pressed
        if (backgroundPressedColor != -2) {
            GradientDrawable shapePressed = new GradientDrawable();//对应xml中
            shapePressed.setColor(backgroundPressedColor);
            if (backgroundRadius != -1) {
                shapePressed.setCornerRadius(backgroundRadius);
            }
            if (backgroundStrokeWidth != -1 && backgroundStrokeColor != -2) {
                shapePressed.setStroke(backgroundStrokeWidth, backgroundStrokeColor);
            }
            setRadius(shapePressed);
            stateListDrawable.addState(STATE_PRESSED, shapePressed);
        }
        //enable_false
        if (backgroundEnableFalseColor != -2) {
            GradientDrawable shapeEnableFalse = new GradientDrawable();
            shapeEnableFalse.setColor(backgroundEnableFalseColor);
            if (backgroundRadius != -1) {
                shapeEnableFalse.setCornerRadius(backgroundRadius);
            }
            if (backgroundStrokeWidth != -1 && backgroundStrokeColor != -2) {
                shapeEnableFalse.setStroke(backgroundStrokeWidth, backgroundStrokeColor);
            }
            setRadius(shapeEnableFalse);
            stateListDrawable.addState(STATE_ENABLE_FALSE, shapeEnableFalse);
        }
        //normal
        if (backgroundNormalColor != -2) {
            GradientDrawable shapeNormal = new GradientDrawable();
            shapeNormal.setColor(backgroundNormalColor);
            if (backgroundRadius != -1) {
                shapeNormal.setCornerRadius(backgroundRadius);
            }
            if (backgroundStrokeWidth != -1 && backgroundStrokeColor != -2) {
                shapeNormal.setStroke(backgroundStrokeWidth, backgroundStrokeColor);
            }
            setRadius(shapeNormal);
            stateListDrawable.addState(STATE_NORMAL, shapeNormal);
        }
        setBackground(stateListDrawable);
    }
}

3.圆角按钮RadiusCornersButton使用

<控件所在包名.RadiusCornersButton
                        android:id="@+id/submit_apply"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@string/submit_apply"
                        android:textColor="@color/white"
                        android:textSize="@dimen/dimen_px2sp_24"
                        app:background_enable_false_color="@color/color_f24c23_40"
                        app:background_normal_color="@color/color_f24c23"
                        app:background_pressed_color="@color/DE4A27"
                        app:background_radius="@dimen/dimen_px_10"
/>

自定义RadiusCornersButton坑点说明

  1. RadiusCornersButton继承Button报红需要继承AppCompatButton
  2. 颜色值不要设置默认值为-1;TypedArray的getColor方法在颜色设置为白色的时候返回-1。why:白色的16进制 #FFFFFF, 不设置不透明度默认FF ,ARGB合起来 #FFFFFFFF,这个不就是整数-1
  3. xml中的selector对应java中的StateListDrawable;xml中的shape对应java中的GradientDrawable

此文要是对你有帮助,如果方便麻烦点个赞,谢谢!!!

你可能感兴趣的:(Android,自定义圆角按钮控件,设置控件为圆角)