你的位置:首页 > 操作系统

[操作系统]自定义控件——开关按钮ToggleButton


  实现一个类似于ToggleButton的开关按钮

  效果图:

  

  资源图片:

  

  1.自定义控件类

  

 1 package com.dc.customview.view; 2  3 import com.dc.customview.R; 4  5 import android.content.Context; 6 import android.graphics.Bitmap; 7 import android.graphics.BitmapFactory; 8 import android.graphics.Canvas; 9 import android.util.AttributeSet; 10 import android.view.MotionEvent; 11 import android.view.View; 12  13 public class CustomToggleButton extends View { 14   private boolean state;//开关状态,默认false,关 15   private boolean isTounching;//是否触摸状态 16   private int currentX; 17   private Bitmap backBitmap; 18   private Bitmap overBitmap; 19    20   /** 21    * 有style文件时调用 22    * @param context 23    * @param attrs 24    * @param defStyle 25   */ 26   public CustomToggleButton(Context context, AttributeSet attrs, int defStyle) { 27     super(context, attrs, defStyle); 28   } 29  30   /** 31    *  32    * @param context 33    * @param attrs 34   */ 35   public CustomToggleButton(Context context, AttributeSet attrs) { 36     super(context, attrs); 37   } 38   /** 39    * java代码中调用 40    * @param context 41   */ 42   public CustomToggleButton(Context context) { 43     super(context); 44   } 45    46   /** 47    * 设置开关状态 48    * @param value 49   */ 50   public void setState(boolean value){ 51     this.state = value; 52   } 53   /** 54    * 获取开关状态 55    * @param value 56    * @return 57   */ 58   public boolean getState(boolean value){ 59     return state; 60   } 61    62   /** 63    * 先拿到自定义控件需要的两张图片,并且设置自定义控件的宽高 64    * 如果不设置,则这个自定义控件可以接收到全屏的触摸事件,即相当于这个自定义控件占了全屏 65    * @param widthMeasureSpec 66    * @param heightMeasureSpec 67   */ 68   @Override 69   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 70     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 71     //底层图片 72     backBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.switch_background); 73     //上层图片 74     overBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.slide_button_background); 75  76     //宽高 和 底层图片一样 77     setMeasuredDimension(backBitmap.getWidth(), backBitmap.getHeight()); 78   } 79    80   /** 81    * 绘制开关 82    * @param canvas 83   */ 84   @Override 85   protected void onDraw(Canvas canvas) { 86     super.onDraw(canvas); 87     //1.绘制底层图片 88     canvas.drawBitmap(backBitmap, 0, 0, null); 89      90     //2.绘制上层图片 91     if(isTounching){//上层图片跟随滑动 92        93       /* 94        * 防止上层图片滑动出下层图片的范围 95       */ 96       //算出当前触摸点为上层图片的中心点时,上层图片的左侧坐标距离 97       int left = currentX-overBitmap.getWidth()/2; 98        99       if(left<0){//防止左侧出界100         left = 0;101       }else if(left > backBitmap.getWidth() - overBitmap.getWidth()){//防止右侧出界102         left = backBitmap.getWidth() - overBitmap.getWidth();103       }104       canvas.drawBitmap(overBitmap, left, 0, null);105       106     }else{//上层图片直接跳到开或关的位置107       if(state){108         //开109         canvas.drawBitmap(overBitmap, backBitmap.getWidth()-overBitmap.getWidth(), 0, null);110       }else{111         //关112         canvas.drawBitmap(overBitmap, 0, 0, null);113       }114     }115     116   }117   /**118    * 触摸滑动开关119    * @param event120    * @return121   */122   @Override123   public boolean onTouchEvent(MotionEvent event) {124     switch (event.getAction()) {125     case MotionEvent.ACTION_DOWN:126       //按下时,触摸状态为true127       isTounching = true;128       //当前触摸点的x坐标129       currentX = (int) event.getX();130       break;131     case MotionEvent.ACTION_MOVE:132       isTounching = true;133       currentX = (int) event.getX();134       break;135     case MotionEvent.ACTION_UP:136       //抬起时触摸状态为false137       isTounching = false;138       currentX = (int) event.getX();139       break;140     }141     142     //触摸点超过底层图片的一半,则state为true,开的状态143     state = currentX > backBitmap.getWidth()/2;144     //重新绘制145     invalidate();146     return true;//自己处理触摸事件147   }148   149   150 151 }

  2.

 1 <RelativeLayout  2    3   android:layout_width="match_parent" 4   android:layout_height="match_parent" 5   android:paddingBottom="@dimen/activity_vertical_margin" 6   android:paddingLeft="@dimen/activity_horizontal_margin" 7   android:paddingRight="@dimen/activity_horizontal_margin" 8   android:paddingTop="@dimen/activity_vertical_margin" 9   tools:context=".MainActivity" >10   <!-- 自定义控件类的全类名 -->11   <com.dc.customview.view.CustomToggleButton12     android:layout_width="wrap_content"13     android:layout_height="wrap_content"14     android:layout_centerInParent="true">15     16   </com.dc.customview.view.CustomToggleButton>17 18 </RelativeLayout>

  以上,将Demo运行到模拟器上即可。

  图解: