android自定義控件,動態設置Button的樣式



今天來看一個通過重寫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,實現多個控件的組合,讓不同項目應用,可避免每次都要重寫


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM