android自定义控件,动态设置Button的样式

jopen 9年前


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

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

下面来看几张效果图:

android自定义控件,动态设置Button的样式 android自定义控件,动态设置Button的样式

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

android自定义控件,动态设置Button的样式 android自定义控件,动态设置Button的样式

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

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

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

package landptf.control;  import android.content.Context;  import android.graphics.Color;  import android.graphics.drawable.GradientDrawable;  import android.util.AttributeSet;  import android.view.Gravity;  import android.view.MotionEvent;  import android.view.View;  import android.widget.Button;  /**   * 重写Button,自定义Button样式   * @author landptf   * @date 2015-6-8   */  public class ButtonM extends Button{    private GradientDrawable gradientDrawable;//控件的样式    private String backColors = "";//背景色,String类型    private int backColori = 0;//背景色,int类型    private String backColorSelecteds = "";//按下后的背景色,String类型    private int backColorSelectedi = 0;//按下后的背景色,int类型    private int backGroundImage = 0;//背景图,只提供了Id    private int backGroundImageSeleted = 0;//按下后的背景图,只提供了Id    private String textColors = "";//文字颜色,String类型    private int textColori = 0;//文字颜色,int类型    private String textColorSeleteds = "";//按下后的文字颜色,String类型    private int textColorSeletedi = 0;//按下后的文字颜色,int类型    private float radius = 8;//圆角半径    private int shape = 0;//圆角样式,矩形、圆形等,由于矩形的Id为0,默认为矩形    private Boolean fillet = false;//是否设置圆角    public ButtonM(Context context, AttributeSet attrs, int defStyle) {      super(context, attrs, defStyle);      init();    }    public ButtonM(Context context, AttributeSet attrs) {      this(context, attrs, 0);    }    public ButtonM(Context context) {      this(context, null);    }    private void init() {      //将Button的默认背景色改为透明,本人不喜欢原来的颜色      if (fillet) {        if (gradientDrawable == null) {          gradientDrawable = new GradientDrawable();        }        gradientDrawable.setColor(Color.TRANSPARENT);      }else {        setBackgroundColor(Color.TRANSPARENT);      }      //设置文字默认居中      setGravity(Gravity.CENTER);      //设置Touch事件      setOnTouchListener(new OnTouchListener() {        @Override        public boolean onTouch(View arg0, MotionEvent event) {          //按下改变样式          setColor(event.getAction());          //此处设置为false,防止Click事件被屏蔽          return false;        }      });    }    //改变样式    private void setColor(int state){      if (state == MotionEvent.ACTION_DOWN) {        //按下        if (backColorSelectedi != 0) {          //先判断是否设置了按下后的背景色int型          if (fillet) {            if (gradientDrawable == null) {              gradientDrawable = new GradientDrawable();            }            gradientDrawable.setColor(backColorSelectedi);          }else {            setBackgroundColor(backColorSelectedi);          }        }else if (!backColorSelecteds.equals("")) {          if (fillet) {            if (gradientDrawable == null) {              gradientDrawable = new GradientDrawable();            }            gradientDrawable.setColor(Color.parseColor(backColorSelecteds));          }else {            setBackgroundColor(Color.parseColor(backColorSelecteds));          }        }        //判断是否设置了按下后文字的颜色        if (textColorSeletedi != 0) {          setTextColor(textColorSeletedi);        }else if (!textColorSeleteds.equals("")) {          setTextColor(Color.parseColor(textColorSeleteds));        }        //判断是否设置了按下后的背景图        if (backGroundImageSeleted != 0) {          setBackgroundResource(backGroundImageSeleted);        }      }      if (state == MotionEvent.ACTION_UP) {        //抬起        if (backColori == 0 && backColors.equals("")) {          //如果没有设置背景色,默认改为透明          if (fillet) {            if (gradientDrawable == null) {              gradientDrawable = new GradientDrawable();            }            gradientDrawable.setColor(Color.TRANSPARENT);          }else {            setBackgroundColor(Color.TRANSPARENT);          }        }else if(backColori != 0){          if (fillet) {            if (gradientDrawable == null) {              gradientDrawable = new GradientDrawable();            }            gradientDrawable.setColor(backColori);          }else {            setBackgroundColor(backColori);          }        }else {          if (fillet) {            if (gradientDrawable == null) {              gradientDrawable = new GradientDrawable();            }            gradientDrawable.setColor(Color.parseColor(backColors));          }else {            setBackgroundColor(Color.parseColor(backColors));          }        }        //如果为设置字体颜色,默认为黑色        if (textColori == 0 && textColors.equals("")) {          setTextColor(Color.BLACK);        }else if (textColori != 0) {          setTextColor(textColori);        }else {          setTextColor(Color.parseColor(textColors));        }        if (backGroundImage != 0) {          setBackgroundResource(backGroundImage);        }      }    }    /**     * 设置按钮的背景色,如果未设置则默认为透明     * @param backColor     */    public void setBackColor(String backColor) {      this.backColors = backColor;      if (backColor.equals("")) {        if (fillet) {          if (gradientDrawable == null) {            gradientDrawable = new GradientDrawable();          }          gradientDrawable.setColor(Color.TRANSPARENT);        }else {          setBackgroundColor(Color.TRANSPARENT);        }      }else {        if (fillet) {          if (gradientDrawable == null) {            gradientDrawable = new GradientDrawable();          }          gradientDrawable.setColor(Color.parseColor(backColor));        }else {          setBackgroundColor(Color.parseColor(backColor));        }      }    }    /**     * 设置按钮的背景色,如果未设置则默认为透明     * @param backColor     */    public void setBackColor(int backColor) {      this.backColori = backColor;      if (backColori == 0) {        if (fillet) {          if (gradientDrawable == null) {            gradientDrawable = new GradientDrawable();          }          gradientDrawable.setColor(Color.TRANSPARENT);        }else {          setBackgroundColor(Color.TRANSPARENT);        }      }else {        if (fillet) {          if (gradientDrawable == null) {            gradientDrawable = new GradientDrawable();          }          gradientDrawable.setColor(backColor);        }else {          setBackgroundColor(backColor);        }      }    }    /**     * 设置按钮按下后的颜色     * @param backColorSelected     */    public void setBackColorSelected(int backColorSelected) {      this.backColorSelectedi = backColorSelected;    }    /**     * 设置按钮按下后的颜色     * @param backColorSelected     */    public void setBackColorSelected(String backColorSelected) {      this.backColorSelecteds = backColorSelected;    }    /**     * 设置按钮的背景图     * @param backGroundImage     */    public void setBackGroundImage(int backGroundImage) {      this.backGroundImage = backGroundImage;      if (backGroundImage != 0) {        setBackgroundResource(backGroundImage);      }    }    /**     * 设置按钮按下的背景图     * @param backGroundImageSeleted     */    public void setBackGroundImageSeleted(int backGroundImageSeleted) {      this.backGroundImageSeleted = backGroundImageSeleted;    }    /**     * 设置按钮圆角半径大小     * @param radius     */    public void setRadius(float radius) {      if (gradientDrawable == null) {        gradientDrawable = new GradientDrawable();      }      gradientDrawable.setCornerRadius(radius);    }    /**     * 设置按钮文字颜色     * @param textColor     */    public void setTextColors(String textColor) {      this.textColors = textColor;      setTextColor(Color.parseColor(textColor));    }    /**     * 设置按钮文字颜色     * @param textColor     */    public void setTextColori(int textColor) {      this.textColori = textColor;      setTextColor(textColor);    }    /**     * 设置按钮按下的文字颜色     * @param textColor     */    public void setTextColorSelected(String textColor) {      this.textColorSeleteds = textColor;    }    /**     * 设置按钮按下的文字颜色     * @param textColor     */    public void setTextColorSelected(int textColor) {      this.textColorSeletedi = textColor;    }    /**     * 按钮的形状     * @param shape     */    public void setShape(int shape) {      this.shape = shape;    }    /**     * 设置其是否为圆角     * @param fillet     */    @SuppressWarnings("deprecation")    public void setFillet(Boolean fillet) {      this.fillet = fillet;      if (fillet) {        if (gradientDrawable == null) {          gradientDrawable = new GradientDrawable();        }        //GradientDrawable.RECTANGLE        gradientDrawable.setShape(shape);        gradientDrawable.setCornerRadius(radius);        setBackgroundDrawable(gradientDrawable);      }    }  }

2 activity_buttonm.xml 布局文件,为了演示效果定义了三个空的LinearLayout,下面将分别为其添加子控件
<?xml version="1.0" encoding="utf-8"?>  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <LinearLayout       android:id="@+id/ll_button1"      android:layout_width="match_parent"      android:layout_height="wrap_content"      android:layout_marginTop="30dp"      android:orientation="horizontal">    </LinearLayout>    <LinearLayout       android:id="@+id/ll_button2"      android:layout_width="match_parent"      android:layout_height="wrap_content"      android:layout_marginTop="30dp"      android:orientation="horizontal">    </LinearLayout>    <LinearLayout       android:id="@+id/ll_button3"      android:layout_width="match_parent"      android:layout_height="wrap_content"      android:layout_marginTop="30dp"      android:orientation="horizontal">    </LinearLayout>  </LinearLayout>

3 ButtonMActivity.java:ButtonM测试类
package landptf.control;  import android.app.Activity;  import android.graphics.Color;  import android.graphics.drawable.GradientDrawable;  import android.os.Bundle;  import android.view.View;  import android.view.View.OnClickListener;  import android.view.ViewGroup.LayoutParams;  import android.widget.LinearLayout;  import android.widget.Toast;  /**   * ButtonM测试类   * @author landptf   * @date 2015-6-8   */  public class ButtonMActivity extends Activity{    //定义三个空布局用来装载Button控件,只为演示效果,实际开发中不推荐使用    private LinearLayout llButtonM1;    private LinearLayout llButtonM2;    private LinearLayout llButtonM3;    //定义三个ButtonM数组    private ButtonM[] buttonM1;    private ButtonM[] buttonM2;    private ButtonM[] buttonM3;    //定义两组颜色值,按下与未按下的按钮背景色    private static final String[] colorList = {"#7067E2","#FF618F","#B674D2","#00C2EB"};    private static final String[] colorSelectedList = {"#3C3779","#88354C","#613E70","#00677D"};    @Override    protected void onCreate(Bundle savedInstanceState) {      super.onCreate(savedInstanceState);      setContentView(R.layout.activity_buttonm);      initView();    }    //初始化控件    private void initView() {      //实例化布局控件      llButtonM1 = (LinearLayout) findViewById(R.id.ll_button1);      llButtonM2 = (LinearLayout) findViewById(R.id.ll_button2);      llButtonM3 = (LinearLayout) findViewById(R.id.ll_button3);      //实例化控件数组,各定义4个      buttonM1 = new ButtonM[4];      buttonM2 = new ButtonM[4];      buttonM3 = new ButtonM[4];      //获取屏幕的宽度,每行四个Button,间隙为60共300,除4为每个控件的宽度      @SuppressWarnings("deprecation")      int btnWidth = (getWindowManager().getDefaultDisplay().getWidth() - 300)/4;      //定义第一个布局      LinearLayout.LayoutParams lp1;      for (int i = 0; i < 4; i++) {        //为buttonM1设置样式,直角矩形        buttonM1[i] = new ButtonM(this);        //字体颜色        buttonM1[i].setTextColori(android.graphics.Color.WHITE);        //字体大小        buttonM1[i].setTextSize(14);        //背景色        buttonM1[i].setBackColor(Color.parseColor(colorList[i]));        //选中的背景色        buttonM1[i].setBackColorSelected(Color.parseColor(colorSelectedList[i]));        //文字提示        buttonM1[i].setText("TEXT" + i);        //此处设置Id的值为i,否则onClick中v.getId()将永远为-1        buttonM1[i].setId(i);        //定义buttonM1的布局,宽度自适应,高度为宽度的0.6倍,权重为1        //也可以写成lp1 = new LinearLayout.LayoutParams(btnWidth,(int) (btnWidth * 0.6));        lp1 = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,(int) (btnWidth * 0.6), 1.0f);        //控件距离其右侧控件的距离,此处为60        lp1.setMargins(0,0,60,0);        buttonM1[i].setLayoutParams(lp1);        //设置buttonM1的点击事件        buttonM1[i].setOnClickListener(new OnClickListener() {          @Override          public void onClick(View v) {            Toast.makeText(ButtonMActivity.this, "您选择了第" + v.getId() + "个", Toast.LENGTH_SHORT).show();          }        });        //设置PaddingLeft为60        llButtonM1.setPadding(60, 0, 0, 0);        //将buttonM1添加到llButtonM1中        llButtonM1.addView(buttonM1[i]);      }      //定义第二个布局      LinearLayout.LayoutParams lp2;      for (int i = 0; i < 4; i++) {        //为buttonM2设置样式,圆角矩形        buttonM2[i] = new ButtonM(this);        buttonM2[i].setTextColori(android.graphics.Color.WHITE);        buttonM2[i].setTextSize(14);        //设置是否为圆角        buttonM2[i].setFillet(true);        //设置圆角的半径大小        buttonM2[i].setRadius(18);        buttonM2[i].setBackColor(Color.parseColor(colorList[i]));        buttonM2[i].setBackColorSelected(Color.parseColor(colorSelectedList[i]));        buttonM2[i].setText("TEXT" + i);        buttonM2[i].setId(i);        lp2 = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,(int) (btnWidth * 0.6), 1.0f);        lp2.setMargins(0,0,60,0);        buttonM2[i].setLayoutParams(lp2);        buttonM2[i].setOnClickListener(new OnClickListener() {          @Override          public void onClick(View v) {            Toast.makeText(ButtonMActivity.this, "您选择了第" + v.getId() + "个", Toast.LENGTH_SHORT).show();          }        });        llButtonM2.setPadding(60, 0, 0, 0);        llButtonM2.addView(buttonM2[i]);      }      //定义第三个布局      LinearLayout.LayoutParams lp3;      for (int i = 0; i < 4; i++) {        //为buttonM3设置样式,圆形        buttonM3[i] = new ButtonM(this);        buttonM3[i].setTextColori(android.graphics.Color.WHITE);        buttonM3[i].setTextSize(14);        //设置为圆形,默认为矩形,GradientDrawable.RECTANGLE        buttonM3[i].setShape(GradientDrawable.OVAL);        buttonM3[i].setFillet(true);        buttonM3[i].setBackColor(Color.parseColor(colorList[i]));        buttonM3[i].setBackColorSelected(Color.parseColor(colorSelectedList[i]));        buttonM3[i].setText("TEXT" + i);        buttonM3[i].setId(i);        lp3 = new LinearLayout.LayoutParams(btnWidth,btnWidth);        lp3.setMargins(0,0,60,0);        buttonM3[i].setLayoutParams(lp3);        buttonM3[i].setOnClickListener(new OnClickListener() {          @Override          public void onClick(View v) {            Toast.makeText(ButtonMActivity.this, "您选择了第" + v.getId() + "个", Toast.LENGTH_SHORT).show();          }        });        llButtonM3.setPadding(60, 0, 0, 0);        llButtonM3.addView(buttonM3[i]);      }    }  }

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

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