实现一个类似于ToggleButton的开关按钮
效果图:
images/loading.gif' data-original="http://images2015.cnblogs.com/blog/985164/201610/985164-20161009163816009-252796523.png" />
资源图片:
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运行到模拟器上即可。
图解:
原标题:自定义控件——开关按钮ToggleButton
关键词: