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

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

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

时间: 2024-10-10 23:44:23

Android中快速便捷的实现圆角按钮方法详解的相关文章

Android中gson、jsonobject解析JSON的方法详解_Android

JSON的定义: 一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性.业内主流技术为其提供了完整的解决方案(有点类似于正则表达式 ,获得了当今大部分语言的支持),从而可以在不同平台间进行数据交换.JSON采用兼容性很高的文本格式,同时也具备类似于C语言体系的行为. JSON对象: JSON中对象(Object)以"{"开始, 以"}"结束. 对象中的每一个item都是一个key-value对, 表现为"key:value"的形式, ke

Android中gson、jsonobject解析JSON的方法详解

JSON的定义: 一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性.业内主流技术为其提供了完整的解决方案(有点类似于正则表达式 ,获得了当今大部分语言的支持),从而可以在不同平台间进行数据交换.JSON采用兼容性很高的文本格式,同时也具备类似于C语言体系的行为. JSON对象: JSON中对象(Object)以"{"开始, 以"}"结束. 对象中的每一个item都是一个key-value对, 表现为"key:value"的形式, ke

读写Android中assets目录下的文件的方法详解_Android

Android资源文件大致可以分为两种: 第一种是res目录下存放的可编译的资源文件: 这种资源文件系统会在R.java里面自动生成该资源文件的ID,所以访问这种资源文件比较简单,通过R.XXX.ID即可: 第二种是assets目录下存放的原生资源文件: 因为系统在编译的时候不会编译assets下的资源文件,所以我们不能通过R.XXX.ID的方式访问它们.那我么能不能通过该资源的绝对路径去访问它们呢?因为apk安装之后会放在/data/app/**.apk目录下,以apk形式存在,asset/r

读写Android中assets目录下的文件的方法详解

Android资源文件大致可以分为两种: 第一种是res目录下存放的可编译的资源文件: 这种资源文件系统会在R.java里面自动生成该资源文件的ID,所以访问这种资源文件比较简单,通过R.XXX.ID即可: 第二种是assets目录下存放的原生资源文件: 因为系统在编译的时候不会编译assets下的资源文件,所以我们不能通过R.XXX.ID的方式访问它们.那我么能不能通过该资源的绝对路径去访问它们呢?因为apk安装之后会放在/data/app/**.apk目录下,以apk形式存在,asset/r

Android中SeekBar拖动条控件使用方法详解

SeekBar拖动条控件使用方法,具体内容如下 一.简介 1. 二.SeekBar拖动条控件使用方法 1.创建SeekBar控件 <SeekBar android:id="@+id/SeekBar1" android:layout_width="match_parent" android:layout_height="wrap_content" android:progress="30" /> 2.添加setOnS

Android 中倒计时验证两种常用方式实例详解

Android 中倒计时验证两种常用方式实例详解 短信验证码功能,这里总结了两种常用的方式,可以直接拿来使用.看图: 说明:这里的及时从10开始,是为了演示的时间不要等太长而修改的. 1.第一种方式:Timer /** * Description:自定义Timer * <p> * Created by Mjj on 2016/12/4. */ public class TimeCount extends CountDownTimer { private Button button; //参数依

Android中屏幕密度和图片大小的关系详解

Android中屏幕密度和图片大小的关系详解 前言 Android中支持许多资源,包括图片(Bitmap),对应于bitmap的文件夹是drawable,除了drawable,还有drawable-ldpi.drawable-mdpi.drawable-hdpi.drawable-xhdpi.drawable-xxhdpi等,同一张图片放到上面不同的文件夹中是有区别的,比如一张100 * 100像素大小的图片,分别放在上述各个文件夹中,然后将其设置为ImageView(假设宽高都是wrap_co

Android TextView使用SpannableString设置复合文本的方法详解_Android

本文实例讲述了Android TextView使用SpannableString设置复合文本的方法.分享给大家供大家参考,具体如下: TextView通常用来显示普通文本,但是有时候需要对其中某些文本进行样式.事件方面的设置.Android系统通过SpannableString类来对指定文本进行相关处理,具体有以下功能: 1.BackgroundColorSpan 背景色 2.ClickableSpan 文本可点击,有点击事件 3.ForegroundColorSpan 文本颜色(前景色) 4.

Android Service生命周期 Service里面的onStartCommand()方法详解

在Demo上,Start一个Service之后,执行顺序:onCreate - > onStartCommand 然后关闭应用,会重新执行上面两步. 但是把代码拷贝到游戏工程发现,关闭游戏后,只执行了onStart,却没有执行onStartCommand! 查找到下面的文章: [plain] view plain copy   Service里面的onStartCommand()方法详解      启动service的时候,onCreate方法只有第一次会调用,onStartCommand和on