自定义控件:滑动开关
ToggleButton 滑動開關
項目概述
滑動開關是一個純粹的自定義控件,上面的按鈕會隨著我們的左右滑動而滑動,并且在狀態改變時通知用戶,效果如下圖1-9 所示,這也是應用中設置某些狀態信息時最常見的控件,因此,我們有必要學習關于如何
自定義一個這樣的滑動開關。
滑動開關UI
布局文件為activity_main.xml,代碼如下:res/layout/activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:itheima="http://schemas.android.com/apk/res/com.itheima.togglebuttondemo"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"><com.itheima.togglebuttondemo.view.ToggleButton android:id="@+id/togglebutton"android:layout_width="wrap_content"android:layout_centerInParent="true"itheima:SwitchBtnBackgroud="@drawable/switch_background"itheima:SlidBtnBackgroud="@drawable/slide_button_background"itheima:CurrentState="false"android:layout_height="wrap_content"/> </RelativeLayout>在activity_main.xml 布局中引入如下命名空間:
xmlns:itheima=”http://schemas.android.com/apk/res/com.itheima.togglebuttondemo”,com.itheima.togglebuttondemo 是包名,itheima 是自定義的命名控件名,可以任取名字,也可以使用類名。
上面的布局主要是引入com.itheima.togglebuttondemo.view.ToggleButton 類和自定義屬性的使用。添加自定義屬性,在values 目錄下創建attrs.xml 文件,具體代碼如文件所示:res/values/attrs.xml
attrs.xml 文件目錄結構如下圖所示:
滑動開關業務邏輯實現
下拉選擇框activity 界面,MainActivity.java 代碼如下:com/itheima/MySwitch/MainActivity
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ToggleButton togglebutton = (ToggleButton) findViewById(R.id.togglebutton);//設置滑動開關的背景圖片// togglebutton.setSwitchBtnBackgroudResource(R.drawable.switch_background);//設置滑動塊的背景圖片// togglebutton.setSlidBtnBackgroudResource(R.drawable.slide_button_background);//設置滑動開關的默認狀態// togglebutton.setCurrentState(true);//設置滑動開關狀態改變監聽Togglebutton.setToggleBtnStateChangeListener(new ToggleBtnStateChangeListener() {@Overridepublic void onToggleBtnStateChange(boolean currentState) {if (currentState) {Toast.makeText(getApplicationContext(), "開關打開", 0).show();}else{Toast.makeText(getApplicationContext(), "開關關閉", 0).show();}}});} }自定義的滑動開關ToggleButton 類的實現,具體代碼如文件所示:com/itheima/MySwitch/MainActivity
public class ToggleButton extends View {private Bitmap switchBitmap;//滑動開關的背景圖片private Bitmap slidBitmap;//滑動塊的背景圖片private boolean currentState;private int currentX;//手指觸摸點的X 值private boolean isTouching = false;private ToggleBtnStateChangeListener mToggleBtnStateChangeListener;//狀態改變監聽器//在xml 中引用該控件時,調用該方法public ToggleButton(Context context, AttributeSet attrs) {super(context, attrs);String namespace = "http://schemas.android.com/apk/res/com.itheima.togglebuttondemo";currentState = attrs.getAttributeBooleanValue(namespace, "CurrentState", false);int switchBtnBackgroudId =attrs.getAttributeResourceValue(namespace, "SwitchBtnBackgroud", -1);int slidBtnBackgroudId =attrs.getAttributeResourceValue(namespace, "SlidBtnBackgroud", -1);setSwitchBtnBackgroudResource(switchBtnBackgroudId);setSlidBtnBackgroudResource(slidBtnBackgroudId);}//在代碼中創建該控件時,調用該構造方法public ToggleButton(Context context) {super(context);}//設置滑動開關的背景圖片public void setSwitchBtnBackgroudResource(int switchBackground) {switchBitmap = BitmapFactory.decodeResource(getResources(), switchBackground);}// 為了可以高度自定義和增強可擴展性,我們可以給其創建一個自定義控件底部背景了一個方法// 設置滑動塊的背景圖片public void setSlidBtnBackgroudResource(int slideButtonBackground) {slidBitmap = BitmapFactory.decodeResource(getResources(), slideButtonBackground);}//設置滑動開關的默認狀態public void setCurrentState(boolean b) {currentState = b;}// 1、測量滑動開關的寬高// 測量控件的寬高@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);setMeasuredDimension(switchBitmap.getWidth(), switchBitmap.getHeight());}// 2、繪制,畫出我們的滑動開關//canvas:畫布,將圖形繪制在canvas,才能顯示到屏幕上@Overrideprotected void onDraw(Canvas canvas) {//繪制滑動開關的背景圖片canvas.drawBitmap(switchBitmap, 0, 0, null);//繪制滑動塊的背景圖片if(isTouching){//手指觸摸的時候,根據currentx 的值來繪制滑動塊//根據手指的X 值,來繪制滑動塊圖片int left = currentX - slidBitmap.getWidth()/2;if(left < 0){//設置左邊界left = 0;}else if(left > (switchBitmap.getWidth() - slidBitmap.getWidth())){//設置右邊界left = switchBitmap.getWidth() - slidBitmap.getWidth();}canvas.drawBitmap(slidBitmap, left, 0, null);}else{ // 手指離開控件的時候,根據狀態來繪制滑動塊// 根據狀態值,來繪制滑動塊if(currentState){ //當前為true,開關打開,滑動塊顯示在最右邊canvas.drawBitmap(slidBitmap,switchBitmap.getWidth() - slidBitmap.getWidth(),0, null);}else{//當前為false,開關關閉,滑動塊顯示在最左邊canvas.drawBitmap(slidBitmap, 0, 0, null);}}}//當控件被觸摸后,會調用該方法@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN://手指按下isTouching = true;currentX = (int) event.getX();break;case MotionEvent.ACTION_MOVE://手指滑動isTouching= true;currentX = (int) event.getX();break;case MotionEvent.ACTION_UP://手指抬起isTouching = false;currentX = (int) event.getX();int center = switchBitmap.getWidth()/2;//當滑動塊中心點大于滑動開關背景圖片的中心線時,顯示到右邊,當前狀態為trueboolean state = currentState;currentState = currentX > center;if(mToggleBtnStateChangeListener !=null&&state != currentState ){mToggleBtnStateChangeListener.onToggleBtnStateChange(currentState);}break;default:break;}invalidate(); //強制讓控件重新繪制,ondraw;return true; //自己處理觸摸事件}public void setToggleBtnStateChangeListener(ToggleBtnStateChangeListenerlistener){this.mToggleBtnStateChangeListener = listener;}// 定義滑動開關狀態改變的回調接口public interface ToggleBtnStateChangeListener{void onToggleBtnStateChange(boolean currentState);} }運行程序,效果圖如圖1-11 所示。
知識點總結
1.通過setMeasuredDimension 方法,來設置自定義控件的寬高,見ToggleButton 類第42 行
2.View 可以通過invalidate()方法強制讓自己重新繪制,見ToggleButton 類第96 行
3.View 通過實現onTouchEvent 方法來處理手指觸摸事件,見ToggleButton 類第72 行
自定義控件之自定義屬性
當我們使用自定義屬性來自定義控件時,一般分為以下幾個步驟進行設置:
總結
以上是生活随笔為你收集整理的自定义控件:滑动开关的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 自定义控件:Viewpager
- 下一篇: Android下的Linux