自定义圆角button

背景:安卓原生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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值