Android-自定义反色圆角Button
2015-09-02 17:52
531 查看
学习目标:
掌握使用 <shape> 标签和 <selector> 标签 在 Button 视图上的使用。
掌握使用代码代替xml文件的功能,实现同上效果。
掌握自定义属性的使用。
写一个自定义Button配合自定义属性,完成反色效果。
1.> <shape> 标签 与 <selector> 标签
在 drawable 文件夹下新建一个button_shape.xml文件,来对 shape 进行描述
写完之后,便可以在布局文件中,使用 backgroud 来引用这个 shape了
效果如图所示,非常简单
因为Button是可点击的,每一次对 Button进行触碰的时候,都会改变它的状态。
我们可以通过为 Button 的 backgroud 指定一个 处理方案<selector>,来告诉 Button,对于哪一样的状态,用什么用的背景图
drawable >> while_button.xml
针对于反色,我们设定在默认状体下,Button的形状为:蓝色描边线,白底填充,蓝色字体.
drawable >> white_radius_button.xml
当我们点击的时候,修改对应的状态为: 蓝色描边线,蓝色填充,白色字体.
drawable >> white_radius_clicking_button.xml
当然,如上只是设置了Button的形状,但是对于 Button中文字的颜色也需要进行配置.
drawable >> white_font.xml
OK,为Button添加backgroud,以及textcolor
效果如图所示:
2.> StateListDrawable 和 ColorStateList
同样的效果,可以使用代码来实现。
可以使用 GradientDrawable 来代替 Shape.
创建一个继承Button的视图,并在其构造函数中编码:
同样的,使用 StateListDrawable 来代替使用xml来配置 Button在不同状态下的背景图
了解了这个类的相关使用,就可以在代码中同样实现反色效果了。
再布局文件中加入我们自定义的这个Button,可以看到效果:
3.> attrs.xml 文件的使用
很明显,我们不可能为了不同的颜色效果专门写xml文件,或者重新自定义Button.这样我们就需要在使用我们自定义Button的时候,
为其传入我们想要的反色。然后再构建函数中获取我们传入的值,然后再将其作用到Button上.
这样我们就需要自定义属性来帮帮忙了.
第一步. values>>attrs.xml 定义我们想要的属性
第二步,在布局文件中,让视图使用这个属性
首先是申明一个别名
myStyle 就是这个别名,它将在后面使用,可以随便写
再然后就是再我们自定义的组件上写我们的自定义属性了。
myStyle就是我们申明的别名了,后面的属性名就不要乱写了。是 attrs.xml 中定义的属性集中的属性名
第三步,获取我们的自定义属性的值。
4.> InverseColButton
我们定义了两个特别的属性:
其中 inverseColor 是我们希望的反色效果使用的颜色
whiteFillFirst 是说是否使用白色首先作为填充色。这个值的作用,我放在这里的期望是,将反色效果倒置一下.
直接上 InverseColButton 的代码吧。
添加Button,让它们显示一下相反的效果给大伙看看
另外给大家分享一个常用颜色值;
掌握使用 <shape> 标签和 <selector> 标签 在 Button 视图上的使用。
掌握使用代码代替xml文件的功能,实现同上效果。
掌握自定义属性的使用。
写一个自定义Button配合自定义属性,完成反色效果。
1.> <shape> 标签 与 <selector> 标签
在 drawable 文件夹下新建一个button_shape.xml文件,来对 shape 进行描述
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <!-- 圆角半径,越大,则角越圆,越小则角越方 --> <corners android:radius="5dp"/> <!-- 描边线 --> <stroke android:width="5dp" android:color="#6699FF"/> <!-- 填充 --> <solid android:color="#6699FF"/> </shape>
写完之后,便可以在布局文件中,使用 backgroud 来引用这个 shape了
<Button android:text="普通按钮" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#ffffff" <strong>android:background="@drawable/button_shape"</strong>/>
效果如图所示,非常简单
因为Button是可点击的,每一次对 Button进行触碰的时候,都会改变它的状态。
我们可以通过为 Button 的 backgroud 指定一个 处理方案<selector>,来告诉 Button,对于哪一样的状态,用什么用的背景图
drawable >> while_button.xml
<?xml version="1.0" encoding="utf-8" ?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:drawable="@drawable/white_radius_clicking_button"/> <item android:state_pressed="false" android:drawable="@drawable/white_radius_button"/> <!-- 默认时的背景图片--> <item android:drawable="@drawable/white_radius_button" /> </selector>
针对于反色,我们设定在默认状体下,Button的形状为:蓝色描边线,白底填充,蓝色字体.
drawable >> white_radius_button.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <stroke android:width="1dp" android:color="#6699FF"/> <corners android:radius="5dp"/> <solid android:color="@android:color/white"/> </shape>
当我们点击的时候,修改对应的状态为: 蓝色描边线,蓝色填充,白色字体.
drawable >> white_radius_clicking_button.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <corners android:radius="5dp"/> <solid android:color="#6699FF"/> <stroke android:width="1dp" android:color="#6699FF"/> </shape>
当然,如上只是设置了Button的形状,但是对于 Button中文字的颜色也需要进行配置.
drawable >> white_font.xml
<?xml version="1.0" encoding="utf-8" ?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:color="#ffffff"/> <item android:state_pressed="false" android:color="#6699FF"/> <item android:color="#6699FF" /> </selector>
OK,为Button添加backgroud,以及textcolor
<Button android:text="蓝白反色按钮" android:layout_width="match_parent" android:layout_height="wrap_content" <strong>android:textColor="@drawable/white_font" android:background="@drawable/while_button"</strong>/>
效果如图所示:
2.> StateListDrawable 和 ColorStateList
同样的效果,可以使用代码来实现。
可以使用 GradientDrawable 来代替 Shape.
创建一个继承Button的视图,并在其构造函数中编码:
// 相当于创建了 shape GradientDrawable gd = new GradientDrawable(); // 设置 shape 的填充色 gd.setColor(Color.BLACK); // 设置 shape 的圆角 gd.setCornerRadius(10); // 设置 shape 的描边线的宽度和颜色 gd.setStroke(1, Color.BLACK); setBackground(gd);
同样的,使用 StateListDrawable 来代替使用xml来配置 Button在不同状态下的背景图
StateListDrawable statelistDrawable = new StateListDrawable(); int pressed = android.R.attr.state_pressed; int windowfocused = android.R.attr.state_window_focused; // -pressed 相当于 false statelistDrawable.addState(new int[] { pressed, windowfocused },drable0); statelistDrawable.addState(new int[] { -pressed,windowfocused },drable1); <pre name="code" class="java">setBackground(statelistDrawable);
了解了这个类的相关使用,就可以在代码中同样实现反色效果了。
// 定义一个默认填充色 int inverseColor = Color.BLACK; // 统一的圆角半径 int roundRadius = 10; // 统一的描边线的宽度 int strokeWidth = 1; // 描边线的颜色 int strokeColor = inverseColor; /* 先设定默认情况下的形状 */ // 默认状态下的填充色为白色 int defaultFillColor = Color.parseColor("#ffffff"); GradientDrawable defaultGd = new GradientDrawable(); defaultGd.setColor(defaultFillColor); defaultGd.setCornerRadius(roundRadius); defaultGd.setStroke(strokeWidth, strokeColor); /* 再设定按下情况下的形状 */ // 设置反色为我们定义的颜色 int pressedFillColor = inverseColor; GradientDrawable pressedGd = new GradientDrawable(); pressedGd.setColor(pressedFillColor); pressedGd.setCornerRadius(roundRadius); pressedGd.setStroke(strokeWidth, strokeColor); StateListDrawable statelistDrawable = new StateListDrawable(); int pressed = android.R.attr.state_pressed; int windowfocused = android.R.attr.state_window_focused; // 分别为不同的状态装配不同的背景 // "-"号表示该状态值为false .即不匹配 statelistDrawable.addState(new int[] { pressed, windowfocused },pressedGd); statelistDrawable.addState(new int[] { -pressed,windowfocused },defaultGd); setBackground(statelistDrawable); // <span style="font-size:18px;"><strong>另外还需要设置一下字体的颜色的反色效果</strong></span> int[] unpress = new int[]{-pressed,windowfocused}; int[] btnPressed = new int[]{pressed, windowfocused}; int[][] states = new int[][]{unpress,btnPressed }; int[] colors = new int[]{inverseColor,Color.parseColor("#ffffff")}; ColorStateList colorStateList = new ColorStateList(states, colors); this.setTextColor(colorStateList);
再布局文件中加入我们自定义的这个Button,可以看到效果:
3.> attrs.xml 文件的使用
很明显,我们不可能为了不同的颜色效果专门写xml文件,或者重新自定义Button.这样我们就需要在使用我们自定义Button的时候,
为其传入我们想要的反色。然后再构建函数中获取我们传入的值,然后再将其作用到Button上.
这样我们就需要自定义属性来帮帮忙了.
第一步. values>>attrs.xml 定义我们想要的属性
<?xml version="1.0" encoding="utf-8"?> <resources> <!-- 属性集的名 --> <declare-styleable name="inverseColBtn"> <!-- 属性名 , 及属性值的格式 --> <attr name="inverseColor" format="color"/> <attr name="whiteFillFirst" format="boolean" /> </declare-styleable> </resources>
第二步,在布局文件中,让视图使用这个属性
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:myStyle="http://schemas.android.com/apk/res/com.example.buttons" android:layout_width="match_parent" android:layout_height="match_parent" .......> <zy.pointer.custom.InverseColButton android:text="InversColBtn" myStyle:inverseColor="@android:color/black" myStyle:whiteFillFirst="false" android:layout_width="match_parent" android:layout_height="wrap_content" />
首先是申明一个别名
xmlns:myStyle="http://schemas.android.com/apk/res/com.example.buttons"
myStyle 就是这个别名,它将在后面使用,可以随便写
http://schemas.android.com/apk/res/com.example.buttons这一部分呢,前面的照写,后面的那一段就是我们工程的包名
再然后就是再我们自定义的组件上写我们的自定义属性了。
myStyle:inverseColor="@android:color/black" myStyle:whiteFillFirst="false"
myStyle就是我们申明的别名了,后面的属性名就不要乱写了。是 attrs.xml 中定义的属性集中的属性名
第三步,获取我们的自定义属性的值。
public InverseColButton(Context context, AttributeSet attrs) { super(context, attrs); //TypedArray是一个数组容器 //先让属性集的名字 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.inverseColBtn); //防止在XML文件里没有定义,就加上了默认值 //再放属性集里面定义的属性名 int inverseColor = a.getColor(R.styleable.inverseColBtn_inverseColor, Color.BLACK); boolean whiteFillFirst = a.getBoolean(R.styleable.inverseColBtn_whiteFillFirst, true); .......
4.> InverseColButton
我们定义了两个特别的属性:
<?xml version="1.0" encoding="utf-8"?> <resources> <!-- 属性集的名 --> <declare-styleable name="inverseColBtn"> <!-- 属性名 , 及属性值的格式 --> <attr name="inverseColor" format="color"/> <attr name="whiteFillFirst" format="boolean" /> </declare-styleable> </resources>
其中 inverseColor 是我们希望的反色效果使用的颜色
whiteFillFirst 是说是否使用白色首先作为填充色。这个值的作用,我放在这里的期望是,将反色效果倒置一下.
直接上 InverseColButton 的代码吧。
public class InverseColButton extends Button{ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } public InverseColButton(Context context, AttributeSet attrs) { super(context, attrs); //TypedArray是一个数组容器 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.inverseColBtn); //防止在XML文件里没有定义,就加上了默认值,默认反色使用黑色,默认首先使用白色进行填充. int inverseColor = a.getColor(R.styleable.inverseColBtn_inverseColor, Color.BLACK); boolean whiteFillFirst = a.getBoolean(R.styleable.inverseColBtn_whiteFillFirst, true); // 统一的圆角半径 int roundRadius = 10; // 统一的描边线的宽度 int strokeWidth = 1; // 描边线的颜色 int strokeColor = inverseColor; /* 先设定默认情况下的形状 */ // 默认状态下的填充色 int defaultFillColor = Color.WHITE; GradientDrawable whiteFillGd = new GradientDrawable(); whiteFillGd.setColor(defaultFillColor); whiteFillGd.setCornerRadius(roundRadius); whiteFillGd.setStroke(strokeWidth, strokeColor); /* 再设定按下情况下的形状 */ int pressedFillColor = inverseColor; GradientDrawable inverseGd = new GradientDrawable(); inverseGd.setColor(pressedFillColor); inverseGd.setCornerRadius(roundRadius); inverseGd.setStroke(strokeWidth, strokeColor); StateListDrawable statelistDrawable = new StateListDrawable(); int pressed = android.R.attr.state_pressed; int windowfocused = android.R.attr.state_window_focused; // 如果使用白色首先填充,则和以前一样 if(whiteFillFirst){ statelistDrawable.addState(new int[] { pressed, windowfocused },inverseGd); statelistDrawable.addState(new int[] { -pressed,windowfocused },whiteFillGd); }else{ // 否则就是反着的效果 statelistDrawable.addState(new int[] { pressed, windowfocused },whiteFillGd); statelistDrawable.addState(new int[] { -pressed,windowfocused },inverseGd); } setBackground(statelistDrawable); // 另外还需要设置一下字体的颜色的反色效果 int[] unpress = new int[]{-pressed,windowfocused}; int[] pressing = new int[]{pressed, windowfocused}; int[][] states = new int[][]{unpress,pressing}; int[] colors; // 同样的,字体的颜色要和上面的一致. if(whiteFillFirst){ colors = new int[]{inverseColor,Color.WHITE}; }else{ colors = new int[]{Color.WHITE,inverseColor}; } ColorStateList colorStateList = new ColorStateList(states, colors); this.setTextColor(colorStateList); } }
添加Button,让它们显示一下相反的效果给大伙看看
<zy.pointer.custom.InverseColButton android:text="InversColBtn - true" myStyle:inverseColor="#800080" android:layout_width="match_parent" android:layout_height="wrap_content" /> <zy.pointer.custom.InverseColButton android:text="InversColBtn - false" myStyle:inverseColor="#800080" <strong>myStyle:whiteFillFirst="false"</strong> android:layout_width="match_parent" android:layout_height="wrap_content" />
另外给大家分享一个常用颜色值;
相关文章推荐
- Android Wifi 状态监控
- Android中如何实现文件下载
- 在Android开发中替换资源图片不起作用的解决方法
- Android Studio快捷键
- Android拨打电话 java.lang.SecurityException: Permission Denial
- Android属性动画完全解析(下),Interpolator和ViewPropertyAnimator的用法
- Android 绘制圆形进度条
- 使用 Android 自带的 proguard 混淆源码
- Android Studio中Gradle使用详解
- Android文件的下载
- Android项目中如何用好构建神器Gradle?
- Android PhoneGap 利用 Activity 实现 CordovaInterface
- juahya 一个动态解析android layout xml 布局文件的框架
- android 电话状态的监听(来电和去电)
- Android5.0 Gallery2上编译Gallery模块出错
- Android官网Activities文档翻译
- 使用ScrollView属性fillViewport解决android布局不能撑满全屏的问题
- android如何打印当前的线程及进程
- Android 属性动画 (一)
- Android adb常见问题