今天来看一个通过重写Button来动态实现一些效果,如圆角矩形、圆形、按下改变字体,改变背景色,改变背景图等

在此说明一下,这种实现方式绝对不是唯一的,而且通过xml文件即可简单实现,这样做只是为了将控件的样式完全由代码实现,更方便打包应用于其他项目

下面来看几张效果图:

图1 初始状态                                            图2 按下第一行的TEXT0

图3 按下第二行的TEXT1                         图4 按下第三行的TEXT2,按住截屏时,没有截到Toast的提示

下面看代码,共两个类,一个布局文件

1 ButtonM.java:重写Button,可单独打包应用于其他项目

  1. package landptf.control;
  2. import android.content.Context;
  3. import android.graphics.Color;
  4. import android.graphics.drawable.GradientDrawable;
  5. import android.util.AttributeSet;
  6. import android.view.Gravity;
  7. import android.view.MotionEvent;
  8. import android.view.View;
  9. import android.widget.Button;
  10. /**
  11. * 重写Button,自定义Button样式
  12. * @author landptf
  13. * @date 2015-6-8
  14. */
  15. public class ButtonM extends Button{
  16. private GradientDrawable gradientDrawable;//控件的样式
  17. private String backColors = "";//背景色,String类型
  18. private int backColori = 0;//背景色,int类型
  19. private String backColorSelecteds = "";//按下后的背景色,String类型
  20. private int backColorSelectedi = 0;//按下后的背景色,int类型
  21. private int backGroundImage = 0;//背景图,只提供了Id
  22. private int backGroundImageSeleted = 0;//按下后的背景图,只提供了Id
  23. private String textColors = "";//文字颜色,String类型
  24. private int textColori = 0;//文字颜色,int类型
  25. private String textColorSeleteds = "";//按下后的文字颜色,String类型
  26. private int textColorSeletedi = 0;//按下后的文字颜色,int类型
  27. private float radius = 8;//圆角半径
  28. private int shape = 0;//圆角样式,矩形、圆形等,由于矩形的Id为0,默认为矩形
  29. private Boolean fillet = false;//是否设置圆角
  30. public ButtonM(Context context, AttributeSet attrs, int defStyle) {
  31. super(context, attrs, defStyle);
  32. init();
  33. }
  34. public ButtonM(Context context, AttributeSet attrs) {
  35. this(context, attrs, 0);
  36. }
  37. public ButtonM(Context context) {
  38. this(context, null);
  39. }
  40. private void init() {
  41. //将Button的默认背景色改为透明,本人不喜欢原来的颜色
  42. if (fillet) {
  43. if (gradientDrawable == null) {
  44. gradientDrawable = new GradientDrawable();
  45. }
  46. gradientDrawable.setColor(Color.TRANSPARENT);
  47. }else {
  48. setBackgroundColor(Color.TRANSPARENT);
  49. }
  50. //设置文字默认居中
  51. setGravity(Gravity.CENTER);
  52. //设置Touch事件
  53. setOnTouchListener(new OnTouchListener() {
  54. @Override
  55. public boolean onTouch(View arg0, MotionEvent event) {
  56. //按下改变样式
  57. setColor(event.getAction());
  58. //此处设置为false,防止Click事件被屏蔽
  59. return false;
  60. }
  61. });
  62. }
  63. //改变样式
  64. private void setColor(int state){
  65. if (state == MotionEvent.ACTION_DOWN) {
  66. //按下
  67. if (backColorSelectedi != 0) {
  68. //先判断是否设置了按下后的背景色int型
  69. if (fillet) {
  70. if (gradientDrawable == null) {
  71. gradientDrawable = new GradientDrawable();
  72. }
  73. gradientDrawable.setColor(backColorSelectedi);
  74. }else {
  75. setBackgroundColor(backColorSelectedi);
  76. }
  77. }else if (!backColorSelecteds.equals("")) {
  78. if (fillet) {
  79. if (gradientDrawable == null) {
  80. gradientDrawable = new GradientDrawable();
  81. }
  82. gradientDrawable.setColor(Color.parseColor(backColorSelecteds));
  83. }else {
  84. setBackgroundColor(Color.parseColor(backColorSelecteds));
  85. }
  86. }
  87. //判断是否设置了按下后文字的颜色
  88. if (textColorSeletedi != 0) {
  89. setTextColor(textColorSeletedi);
  90. }else if (!textColorSeleteds.equals("")) {
  91. setTextColor(Color.parseColor(textColorSeleteds));
  92. }
  93. //判断是否设置了按下后的背景图
  94. if (backGroundImageSeleted != 0) {
  95. setBackgroundResource(backGroundImageSeleted);
  96. }
  97. }
  98. if (state == MotionEvent.ACTION_UP) {
  99. //抬起
  100. if (backColori == 0 && backColors.equals("")) {
  101. //如果没有设置背景色,默认改为透明
  102. if (fillet) {
  103. if (gradientDrawable == null) {
  104. gradientDrawable = new GradientDrawable();
  105. }
  106. gradientDrawable.setColor(Color.TRANSPARENT);
  107. }else {
  108. setBackgroundColor(Color.TRANSPARENT);
  109. }
  110. }else if(backColori != 0){
  111. if (fillet) {
  112. if (gradientDrawable == null) {
  113. gradientDrawable = new GradientDrawable();
  114. }
  115. gradientDrawable.setColor(backColori);
  116. }else {
  117. setBackgroundColor(backColori);
  118. }
  119. }else {
  120. if (fillet) {
  121. if (gradientDrawable == null) {
  122. gradientDrawable = new GradientDrawable();
  123. }
  124. gradientDrawable.setColor(Color.parseColor(backColors));
  125. }else {
  126. setBackgroundColor(Color.parseColor(backColors));
  127. }
  128. }
  129. //如果为设置字体颜色,默认为黑色
  130. if (textColori == 0 && textColors.equals("")) {
  131. setTextColor(Color.BLACK);
  132. }else if (textColori != 0) {
  133. setTextColor(textColori);
  134. }else {
  135. setTextColor(Color.parseColor(textColors));
  136. }
  137. if (backGroundImage != 0) {
  138. setBackgroundResource(backGroundImage);
  139. }
  140. }
  141. }
  142. /**
  143. * 设置按钮的背景色,如果未设置则默认为透明
  144. * @param backColor
  145. */
  146. public void setBackColor(String backColor) {
  147. this.backColors = backColor;
  148. if (backColor.equals("")) {
  149. if (fillet) {
  150. if (gradientDrawable == null) {
  151. gradientDrawable = new GradientDrawable();
  152. }
  153. gradientDrawable.setColor(Color.TRANSPARENT);
  154. }else {
  155. setBackgroundColor(Color.TRANSPARENT);
  156. }
  157. }else {
  158. if (fillet) {
  159. if (gradientDrawable == null) {
  160. gradientDrawable = new GradientDrawable();
  161. }
  162. gradientDrawable.setColor(Color.parseColor(backColor));
  163. }else {
  164. setBackgroundColor(Color.parseColor(backColor));
  165. }
  166. }
  167. }
  168. /**
  169. * 设置按钮的背景色,如果未设置则默认为透明
  170. * @param backColor
  171. */
  172. public void setBackColor(int backColor) {
  173. this.backColori = backColor;
  174. if (backColori == 0) {
  175. if (fillet) {
  176. if (gradientDrawable == null) {
  177. gradientDrawable = new GradientDrawable();
  178. }
  179. gradientDrawable.setColor(Color.TRANSPARENT);
  180. }else {
  181. setBackgroundColor(Color.TRANSPARENT);
  182. }
  183. }else {
  184. if (fillet) {
  185. if (gradientDrawable == null) {
  186. gradientDrawable = new GradientDrawable();
  187. }
  188. gradientDrawable.setColor(backColor);
  189. }else {
  190. setBackgroundColor(backColor);
  191. }
  192. }
  193. }
  194. /**
  195. * 设置按钮按下后的颜色
  196. * @param backColorSelected
  197. */
  198. public void setBackColorSelected(int backColorSelected) {
  199. this.backColorSelectedi = backColorSelected;
  200. }
  201. /**
  202. * 设置按钮按下后的颜色
  203. * @param backColorSelected
  204. */
  205. public void setBackColorSelected(String backColorSelected) {
  206. this.backColorSelecteds = backColorSelected;
  207. }
  208. /**
  209. * 设置按钮的背景图
  210. * @param backGroundImage
  211. */
  212. public void setBackGroundImage(int backGroundImage) {
  213. this.backGroundImage = backGroundImage;
  214. if (backGroundImage != 0) {
  215. setBackgroundResource(backGroundImage);
  216. }
  217. }
  218. /**
  219. * 设置按钮按下的背景图
  220. * @param backGroundImageSeleted
  221. */
  222. public void setBackGroundImageSeleted(int backGroundImageSeleted) {
  223. this.backGroundImageSeleted = backGroundImageSeleted;
  224. }
  225. /**
  226. * 设置按钮圆角半径大小
  227. * @param radius
  228. */
  229. public void setRadius(float radius) {
  230. if (gradientDrawable == null) {
  231. gradientDrawable = new GradientDrawable();
  232. }
  233. gradientDrawable.setCornerRadius(radius);
  234. }
  235. /**
  236. * 设置按钮文字颜色
  237. * @param textColor
  238. */
  239. public void setTextColors(String textColor) {
  240. this.textColors = textColor;
  241. setTextColor(Color.parseColor(textColor));
  242. }
  243. /**
  244. * 设置按钮文字颜色
  245. * @param textColor
  246. */
  247. public void setTextColori(int textColor) {
  248. this.textColori = textColor;
  249. setTextColor(textColor);
  250. }
  251. /**
  252. * 设置按钮按下的文字颜色
  253. * @param textColor
  254. */
  255. public void setTextColorSelected(String textColor) {
  256. this.textColorSeleteds = textColor;
  257. }
  258. /**
  259. * 设置按钮按下的文字颜色
  260. * @param textColor
  261. */
  262. public void setTextColorSelected(int textColor) {
  263. this.textColorSeletedi = textColor;
  264. }
  265. /**
  266. * 按钮的形状
  267. * @param shape
  268. */
  269. public void setShape(int shape) {
  270. this.shape = shape;
  271. }
  272. /**
  273. * 设置其是否为圆角
  274. * @param fillet
  275. */
  276. @SuppressWarnings("deprecation")
  277. public void setFillet(Boolean fillet) {
  278. this.fillet = fillet;
  279. if (fillet) {
  280. if (gradientDrawable == null) {
  281. gradientDrawable = new GradientDrawable();
  282. }
  283. //GradientDrawable.RECTANGLE
  284. gradientDrawable.setShape(shape);
  285. gradientDrawable.setCornerRadius(radius);
  286. setBackgroundDrawable(gradientDrawable);
  287. }
  288. }
  289. }

2 activity_buttonm.xml 布局文件,为了演示效果定义了三个空的LinearLayout,下面将分别为其添加子控件

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical" >
  6. <LinearLayout
  7. android:id="@+id/ll_button1"
  8. android:layout_width="match_parent"
  9. android:layout_height="wrap_content"
  10. android:layout_marginTop="30dp"
  11. android:orientation="horizontal">
  12. </LinearLayout>
  13. <LinearLayout
  14. android:id="@+id/ll_button2"
  15. android:layout_width="match_parent"
  16. android:layout_height="wrap_content"
  17. android:layout_marginTop="30dp"
  18. android:orientation="horizontal">
  19. </LinearLayout>
  20. <LinearLayout
  21. android:id="@+id/ll_button3"
  22. android:layout_width="match_parent"
  23. android:layout_height="wrap_content"
  24. android:layout_marginTop="30dp"
  25. android:orientation="horizontal">
  26. </LinearLayout>
  27. </LinearLayout>

3 ButtonMActivity.java:ButtonM测试类

  1. package landptf.control;
  2. import android.app.Activity;
  3. import android.graphics.Color;
  4. import android.graphics.drawable.GradientDrawable;
  5. import android.os.Bundle;
  6. import android.view.View;
  7. import android.view.View.OnClickListener;
  8. import android.view.ViewGroup.LayoutParams;
  9. import android.widget.LinearLayout;
  10. import android.widget.Toast;
  11. /**
  12. * ButtonM测试类
  13. * @author landptf
  14. * @date 2015-6-8
  15. */
  16. public class ButtonMActivity extends Activity{
  17. //定义三个空布局用来装载Button控件,只为演示效果,实际开发中不推荐使用
  18. private LinearLayout llButtonM1;
  19. private LinearLayout llButtonM2;
  20. private LinearLayout llButtonM3;
  21. //定义三个ButtonM数组
  22. private ButtonM[] buttonM1;
  23. private ButtonM[] buttonM2;
  24. private ButtonM[] buttonM3;
  25. //定义两组颜色值,按下与未按下的按钮背景色
  26. private static final String[] colorList = {"#7067E2","#FF618F","#B674D2","#00C2EB"};
  27. private static final String[] colorSelectedList = {"#3C3779","#88354C","#613E70","#00677D"};
  28. @Override
  29. protected void onCreate(Bundle savedInstanceState) {
  30. super.onCreate(savedInstanceState);
  31. setContentView(R.layout.activity_buttonm);
  32. initView();
  33. }
  34. //初始化控件
  35. private void initView() {
  36. //实例化布局控件
  37. llButtonM1 = (LinearLayout) findViewById(R.id.ll_button1);
  38. llButtonM2 = (LinearLayout) findViewById(R.id.ll_button2);
  39. llButtonM3 = (LinearLayout) findViewById(R.id.ll_button3);
  40. //实例化控件数组,各定义4个
  41. buttonM1 = new ButtonM[4];
  42. buttonM2 = new ButtonM[4];
  43. buttonM3 = new ButtonM[4];
  44. //获取屏幕的宽度,每行四个Button,间隙为60共300,除4为每个控件的宽度
  45. @SuppressWarnings("deprecation")
  46. int btnWidth = (getWindowManager().getDefaultDisplay().getWidth() - 300)/4;
  47. //定义第一个布局
  48. LinearLayout.LayoutParams lp1;
  49. for (int i = 0; i < 4; i++) {
  50. //为buttonM1设置样式,直角矩形
  51. buttonM1[i] = new ButtonM(this);
  52. //字体颜色
  53. buttonM1[i].setTextColori(android.graphics.Color.WHITE);
  54. //字体大小
  55. buttonM1[i].setTextSize(14);
  56. //背景色
  57. buttonM1[i].setBackColor(Color.parseColor(colorList[i]));
  58. //选中的背景色
  59. buttonM1[i].setBackColorSelected(Color.parseColor(colorSelectedList[i]));
  60. //文字提示
  61. buttonM1[i].setText("TEXT" + i);
  62. //此处设置Id的值为i,否则onClick中v.getId()将永远为-1
  63. buttonM1[i].setId(i);
  64. //定义buttonM1的布局,宽度自适应,高度为宽度的0.6倍,权重为1
  65. //也可以写成lp1 = new LinearLayout.LayoutParams(btnWidth,(int) (btnWidth * 0.6));
  66. lp1 = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,(int) (btnWidth * 0.6), 1.0f);
  67. //控件距离其右侧控件的距离,此处为60
  68. lp1.setMargins(0,0,60,0);
  69. buttonM1[i].setLayoutParams(lp1);
  70. //设置buttonM1的点击事件
  71. buttonM1[i].setOnClickListener(new OnClickListener() {
  72. @Override
  73. public void onClick(View v) {
  74. Toast.makeText(ButtonMActivity.this, "您选择了第" + v.getId() + "个", Toast.LENGTH_SHORT).show();
  75. }
  76. });
  77. //设置PaddingLeft为60
  78. llButtonM1.setPadding(60, 0, 0, 0);
  79. //将buttonM1添加到llButtonM1中
  80. llButtonM1.addView(buttonM1[i]);
  81. }
  82. //定义第二个布局
  83. LinearLayout.LayoutParams lp2;
  84. for (int i = 0; i < 4; i++) {
  85. //为buttonM2设置样式,圆角矩形
  86. buttonM2[i] = new ButtonM(this);
  87. buttonM2[i].setTextColori(android.graphics.Color.WHITE);
  88. buttonM2[i].setTextSize(14);
  89. //设置是否为圆角
  90. buttonM2[i].setFillet(true);
  91. //设置圆角的半径大小
  92. buttonM2[i].setRadius(18);
  93. buttonM2[i].setBackColor(Color.parseColor(colorList[i]));
  94. buttonM2[i].setBackColorSelected(Color.parseColor(colorSelectedList[i]));
  95. buttonM2[i].setText("TEXT" + i);
  96. buttonM2[i].setId(i);
  97. lp2 = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,(int) (btnWidth * 0.6), 1.0f);
  98. lp2.setMargins(0,0,60,0);
  99. buttonM2[i].setLayoutParams(lp2);
  100. buttonM2[i].setOnClickListener(new OnClickListener() {
  101. @Override
  102. public void onClick(View v) {
  103. Toast.makeText(ButtonMActivity.this, "您选择了第" + v.getId() + "个", Toast.LENGTH_SHORT).show();
  104. }
  105. });
  106. llButtonM2.setPadding(60, 0, 0, 0);
  107. llButtonM2.addView(buttonM2[i]);
  108. }
  109. //定义第三个布局
  110. LinearLayout.LayoutParams lp3;
  111. for (int i = 0; i < 4; i++) {
  112. //为buttonM3设置样式,圆形
  113. buttonM3[i] = new ButtonM(this);
  114. buttonM3[i].setTextColori(android.graphics.Color.WHITE);
  115. buttonM3[i].setTextSize(14);
  116. //设置为圆形,默认为矩形,GradientDrawable.RECTANGLE
  117. buttonM3[i].setShape(GradientDrawable.OVAL);
  118. buttonM3[i].setFillet(true);
  119. buttonM3[i].setBackColor(Color.parseColor(colorList[i]));
  120. buttonM3[i].setBackColorSelected(Color.parseColor(colorSelectedList[i]));
  121. buttonM3[i].setText("TEXT" + i);
  122. buttonM3[i].setId(i);
  123. lp3 = new LinearLayout.LayoutParams(btnWidth,btnWidth);
  124. lp3.setMargins(0,0,60,0);
  125. buttonM3[i].setLayoutParams(lp3);
  126. buttonM3[i].setOnClickListener(new OnClickListener() {
  127. @Override
  128. public void onClick(View v) {
  129. Toast.makeText(ButtonMActivity.this, "您选择了第" + v.getId() + "个", Toast.LENGTH_SHORT).show();
  130. }
  131. });
  132. llButtonM3.setPadding(60, 0, 0, 0);
  133. llButtonM3.addView(buttonM3[i]);
  134. }
  135. }
  136. }

注释基本都说明了,可以慢慢积累这些控件,最终形成一个自己的控件库,在不同项目中完善,使之越来越强大

明天给大家介绍一下通过继承RelativeLayout,实现多个控件的组合,让不同项目应用,可避免每次都要重写

android自定义控件,动态设置Button的样式的更多相关文章

  1. android 怎么动态设置button 的style

    网上找了很多,还是没有直接的解决办法,button没有setstyle这个方法.因此我的解决办法如下: 直接动态设置各个属性 Button themeBtn = new Button(this); t ...

  2. JavaScript动态设置div的样式的方法

    有时候需要根据需要动态设置div的样式,当然对于稍有经验的javascript开发者来说,这一切都是那么的简单,但是对于初学者或者说没有相关经验的开发者来说可能就是一个不大不小的难关,下面就通过实例简 ...

  3. 【Android】 TextView设置个别字体样式

    SpannableString msp = new SpannableString("测试"+XM+"更换当前号码将从手机发送一条普通短信进行验证"); msp ...

  4. asp.net动态设置button的Text,Enabled属性,向后台传递参数

    前台代码:根据后台传递过来的参数动态设置 <asp:Button ID="Button1" runat="server" CommandArgument= ...

  5. 【转】三十三、Android给ListView设置分割线Divider样式

    原文网址:http://www.cnblogs.com/linjiqin/archive/2011/11/12/2246349.html 给ListView设置分割线,只需设置如下两个属性: andr ...

  6. Android textView 动态设置代码字号大小,支持单位选项 dp,sp or px

    setTextSize(TypedValue.COMPLEX_UNIT_PX,22); //22像素 setTextSize(TypedValue.COMPLEX_UNIT_SP,22); //22S ...

  7. Android给ListView设置分割线Divider样式

    给ListView设置分割线,只需设置如下两个属性: android:divider="#000" //设置分割线显示颜色 android:dividerHeight=" ...

  8. 【前端_js】jQuery动态设置元素的样式

    1.用css()方法查询元素的某个样式 $("div").css("padding-left")); 2.用css()方法设置元素的样式 法一: $(" ...

  9. android 如何动态设置View的margin和padding

    感谢大佬:https://blog.csdn.net/a107494639/article/details/7341077 1.动态设置padding,拿ImageView为例: ImageView ...

随机推荐

  1. ubuntu14.04下 Android虚拟机 genymotion 的下载和安装

    官网:https://www.genymotion.com/ Install Guide https://www.genymotion.com/#!/developers/user-guide#ins ...

  2. c++的四种强制类型转换

    http://hb.qq.com/a/20110722/001452.htm ...... C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是:TYPE b = (TYPE)a ...

  3. Sharepoint 问题集锦 - 配置

    错误 在sharepoint designer中编辑List的表单的时候,提示soap:Server服务器无法处理请求. ---> 值不在预期的范围内. 解释: 这个是由于我在本地测试的时候,使 ...

  4. POJ 1013 Counterfeit Dollar 集合上的位运算

    Description Sally Jones has a dozen Voyageur silver dollars. However, only eleven of the coins are t ...

  5. Netty启动分析

    基于Netty-3.2.5 先看一段Netty的服务端代码: import java.net.InetSocketAddress; import java.util.concurrent.Execut ...

  6. [UOJ 74] 【UR #6】破解密码

    题目链接:UOJ - 74 题目分析 题目中,将字符串 S 的第一个字符移到末尾,其他字符向前移动一个位置,f(S) 就从 Hi 变成了 Hi+1. 我们分析一下这个过程:假设第一个字符为 c, (H ...

  7. 【HTTP】HTTP access control (CORS)

    https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS Cross-site HTTP requests are H ...

  8. [spring-framework]Spring定时器的配置和使用

    开发中我们常常会做一些定时任务,这些任务有开始时间,并会按一定的周期或规则执行.如此我们在Java程序开发中使用定时器来处理定时任务. <!-- MessageRequestTask类中包含了m ...

  9. spring没能给struts2创建出action,可能出现的原因

    spring没能给struts2创建出action,可能出现的原因: 1.没有加载struts2-spring-plugin-2.1.8.1.jar 2.包冲突,删除asm.jar(网上说的) 3.s ...

  10. 【HDOJ】1811 Rank of Tetris

    并查集+拓扑排序.使用并查集解决a = b的情况. #include <iostream> #include <cstdio> #include <cstring> ...