自定义圆角button

来源:互联网 发布:女生都穿安全裤 知乎 编辑:程序博客网 时间:2024/06/08 19:40

背景:安卓原生button太丑,产品给的设计图花样很多,例如,而且还需设置按下效果。

当然,用selecter写背景是可以的。如果产品的button颜色很多,就需要些一大堆的drawable。为了开发方便,写了一个自定义button。

该button可设置圆角半径,默认半圆。以及可设定按下效果颜色,大大减少了开发时间。


源码:

第一步:在values下创建attrs.xml文件(已存在则跳过)

第二步:在attrs.xml文件中设置自定义属性

<declare-styleable name="FilletButton">    <attr name="text_f" format="string|reference"/>    <attr name="textsize_f" format="dimension"/>    <attr name="textcolor_f" format="color|reference"/>    <attr name="width_f" format="dimension|reference"/>    <attr name="height_f" format="dimension|reference"/>    <attr name="bgcolor_f" format="color|reference"/>    <attr name="bgcolor_press_f" format="color|reference"/>    <attr name="radius_f" format="dimension|reference"/></declare-styleable>
第三步:编写自定义button:

public class FilletButton extends View{    private int textColor = Color.WHITE;//字体颜色    private int bgColor = Color.YELLOW;//背景颜色    private int bgColor_press = Color.GRAY;//按下时背景颜色    private int color_current = Color.GRAY;//当前背景颜色    private Rect mBound;    private Paint p;    private String text;    private float textSize;    private RectF rectF;    private Context context;    private float radius = 0;//圆角半径    public FilletButton(Context context) {        this(context,null);    }    public FilletButton(Context context, @Nullable AttributeSet attrs) {        this(context,attrs,0);    }    public FilletButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        this.context = context;        TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.FilletButton, defStyleAttr, 0);        for (int i = 0; i < array.getIndexCount(); i++) {            int attr = array.getIndex(i);            switch (attr) {                case R.styleable.FilletButton_textsize_f:                    textSize = array.getDimension(attr, 20);                    break;                case R.styleable.FilletButton_textcolor_f:                    textColor = array.getColor(attr, Color.WHITE);                    break;                case R.styleable.FilletButton_bgcolor_f:                    bgColor = array.getColor(attr,Color.YELLOW);                    color_current = bgColor;                    break;                case R.styleable.FilletButton_bgcolor_press_f:                    bgColor_press = array.getColor(attr,Color.YELLOW);                    break;                case R.styleable.FilletButton_text_f:                    text = array.getString(attr);                    break;                case R.styleable.FilletButton_radius_f:                    radius = array.getDimension(attr,0f);                    break;            }        }        array.recycle();        Init();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int heightMode = MeasureSpec.getMode(heightMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        int width;        int height ;        if (widthMode == MeasureSpec.EXACTLY)        {            width = widthSize;        } else {            p.setTextSize(textSize);            p.getTextBounds(text, 0, text.length(), mBound);            float textWidth = mBound.width();            width = (int) (getPaddingLeft() + textWidth + getPaddingRight());        }        if (heightMode == MeasureSpec.EXACTLY)        {            height = heightSize;        } else {            p.setTextSize(textSize);            p.getTextBounds(text, 0, text.length(), mBound);            float textHeight = mBound.height();            height = (int) (getPaddingTop() + textHeight + getPaddingBottom());        }        setMeasuredDimension(width, height);    }    private void Init(){        this.setLayerType(View.LAYER_TYPE_SOFTWARE, null);        p = new Paint();        mBound = new Rect();        rectF = new RectF();    }    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()){            case MotionEvent.ACTION_DOWN:                color_current = bgColor_press;                this.invalidate();                break;            case MotionEvent.ACTION_CANCEL:            case MotionEvent.ACTION_UP:            case MotionEvent.ACTION_OUTSIDE:                color_current =bgColor;                this.invalidate();//重绘控件                break;        }        return super.onTouchEvent(event);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        drawBackground(canvas);        drawText(canvas);    }    private void drawBackground(Canvas canvas){        float mRadius = radius;        if (mRadius == 0.0){            mRadius = getHeight()/2;//默认圆角半径为高度的一半        }else {            mRadius = ScreenUtil.dpToPx(context,radius);        }        rectF.set(0,0,getWidth(),getHeight());        p.setAntiAlias(true);        p.setStyle(Paint.Style.FILL);        p.setColor(color_current);        canvas.drawRoundRect(rectF,mRadius,mRadius,p);    }    private void drawText(Canvas canvas){        if (TextUtils.isEmpty(text)) return;        p.setColor(textColor);        p.setTextSize(textSize);        p.setStyle(Paint.Style.FILL);        Paint.FontMetricsInt fontMetrics = p.getFontMetricsInt();        int baseline = (getHeight() - fontMetrics.bottom - fontMetrics.top) / 2;        // 下面这行是实现水平居中,drawText对应改为传入targetRect.centerX()        p.setTextAlign(Paint.Align.CENTER);        canvas.drawText(text,getWidth()/2, baseline, p);    }    public FilletButton setBackgroundColor(@ColorRes int bgColorId, @ColorRes int bgColor_pressId){        this.bgColor = ContextCompat.getColor(context, bgColorId);        this.bgColor_press = ContextCompat.getColor(context, bgColor_pressId);        color_current = this.bgColor;        return this;    }    public FilletButton setText(@StringRes int strId){        text = context.getString(strId);        return this;    }    public FilletButton setText(String textStr){        text = textStr;        return this;    }    public FilletButton setTextColor(@ColorRes int colorId){        textColor = ContextCompat.getColor(context, colorId);        return this;    }    /**     * 更改样式时需刷新控件     */    public void refresh(){        this.invalidate();    }}
第四步:在需要的地方添加该按钮

<com.woxiu.jifen.view.FilletButton    android:id="@+id/fBtn_shopDetail_item"    android:layout_width="@dimen/dp_75"    android:layout_height="@dimen/dp_24"    app:textcolor_f="@color/c_ffffff"    app:textsize_f="@dimen/dp_12"    app:bgcolor_f="@color/c_ff9933"    app:bgcolor_press_f="@color/c_d5851c"    android:layout_centerVertical="true"    app:text_f="@string/exchange_rightnow"/>

第五步:动态更改button颜色方法:

btn.setText(R.string.exchange_rightnow).setBackgroundColor(R.color.c_ff9933,R.color.c_d5851c).refresh();


Github: https://github.com/rongkun/FilletButton

原创粉丝点击