自定义控件,开关左右滑动

自定义控件一般的思路都是根据图片,自己绘制相应的控件

布局文件

 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 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.itheima27.slidebutton.view.SlideButton
12         android:id="@+id/slidebutton"
13         android:layout_width="wrap_content"
14         android:layout_height="wrap_content"
15         android:layout_centerInParent="true" />
16 
17 </RelativeLayout>

 

 

 

  1 import com.itheima27.slidebutton.R;
  2 import com.itheima27.slidebutton.interf.OnToggleStateChangedListener;
  3 
  4 import android.content.Context;
  5 import android.graphics.Bitmap;
  6 import android.graphics.BitmapFactory;
  7 import android.graphics.Canvas;
  8 import android.util.AttributeSet;
  9 import android.view.MotionEvent;
 10 import android.view.View;
 11 
 12 public class SlideButton extends View {
 13 
 14     private Bitmap switchBG;    // 滑动开关的背景
 15     private Bitmap slideButtonBG; // 滑动块的背景
 16     private boolean currentState = false;    // 开关当前的状态, 默认为: 关闭
 17     private int currentX;    // x轴的偏移量
 18     private boolean isSliding = false;        // 是否正在滑动中
 19     private OnToggleStateChangedListener mListener;
 20 
 21     public SlideButton(Context context, AttributeSet attrs) {
 22         super(context, attrs);
 23         
 24         initBitmap();
 25     }
 26 
 27     /**
 28      * 当测量当前控件的宽高时回调
 29      */
 30     @Override
 31     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 32         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 33         
 34         // 设置开关的宽和高
 35         setMeasuredDimension(switchBG.getWidth(), switchBG.getHeight());
 36     }
 37 
 38     /**
 39      * 绘制当前控件的方法
 40      */
 41     @Override
 42     protected void onDraw(Canvas canvas) {
 43         
 44         // 1. 把滑动开关的背景画到画布上
 45         canvas.drawBitmap(switchBG, 0, 0, null);        // 把背景平铺到控件上
 46         
 47         // 2. 绘制滑动块显示的位置, 开或者关
 48         
 49         if(isSliding) {
 50             int left = currentX - (slideButtonBG.getWidth() / 2);
 51             if(left < 0) {
 52                 left = 0;
 53             } else if(left > switchBG.getWidth() - slideButtonBG.getWidth()) {
 54                 left = switchBG.getWidth() - slideButtonBG.getWidth();
 55             }
 56             
 57             canvas.drawBitmap(slideButtonBG, left, 0, null);
 58         } else {
 59             if(currentState) {    // 绘制开关为开的状态
 60                 canvas.drawBitmap(slideButtonBG, switchBG.getWidth() - slideButtonBG.getWidth(), 0, null);
 61             } else {    // 绘制开关为关的状态
 62                 canvas.drawBitmap(slideButtonBG, 0, 0, null);
 63             }
 64         }
 65         super.onDraw(canvas);
 66     }
 67 
 68     /**
 69      * 当产生触摸时间时回调此方法
 70      */
 71     @Override
 72     public boolean onTouchEvent(MotionEvent event) {
 73         switch (event.getAction()) {
 74         case MotionEvent.ACTION_DOWN: // 按下
 75             currentX = (int) event.getX();
 76             isSliding  = true;
 77             break;
 78         case MotionEvent.ACTION_MOVE: // 移动
 79             currentX = (int) event.getX();
 80             break;
 81         case MotionEvent.ACTION_UP: // 抬起
 82             isSliding = false;
 83             
 84             // 判断当前滑动块, 偏向于哪一边, 如果滑动块的中心点小于背景的中心点, 设置为关闭状态
 85             
 86             int bgCenter = switchBG.getWidth() / 2;
 87             
 88             boolean state = currentX > bgCenter;        // 改变后的状态
 89             
 90             // 调用用户的监听事件
 91             if(state != currentState && mListener != null) {
 92                 mListener.onToggleStateChanged(state);
 93             }
 94 
 95             currentState = state;
 96             break;
 97         default:
 98             break;
 99         }
100 
101         invalidate();        // 刷新当前控件, 会引起onDraw方法的调用
102         return true;
103     }
104 
105     /**
106      * 初始化图片
107      */
108     private void initBitmap() {
109         slideButtonBG = BitmapFactory.decodeResource(getResources(), R.drawable.slide_button_background);
110         switchBG = BitmapFactory.decodeResource(getResources(), R.drawable.switch_background);
111     }
112 
113     /**
114      * 设置开关的状态
115      * @param b
116      */
117     public void setToggleState(boolean b) {
118         currentState = b;
119     }
120 
121     /**
122      * 设置开关状态改变的监听事件
123      * @param listener
124      */
125     public void setOnToggleStateChangedListener(OnToggleStateChangedListener listener) {
126         this.mListener = listener;
127     }
128 }

 

posted on 2015-05-29 17:46  wf110  阅读(537)  评论(0编辑  收藏  举报