自定义控件一般的几个步骤:
1.初始化相关背景图片,布局文件,自定义属性
2.设置控件宽高OnMeasure()
3.布局或者排版OnLayout()
4.绘制控件OnDraw()
5.处理触摸事件OnTouchEvent()
1 public class SwitchView extends View implements View.OnTouchListener {
2
3 //开关状态图片
4 private Bitmap mSwitch_on, mSwitch_off, mSwitch_circle;
5
6 //开关状态 默认关闭
7 private boolean mCurrentState = false;
8
9 //开关切换回调接口
10 private OnSwitchChangedListener mOnSwitchChangedListener;
11
12 //X轴按下坐标
13 private int downX;
14 //X轴移动时触点坐标
15 private int moveX;
16 //X轴偏移量
17 private int left = 0;
18 //最大可移动距离
19 private int max;
20
21 public SwitchView(Context context) {
22 super(context);
23 init();
24 }
25
26 public SwitchView(Context context, AttributeSet attrs) {
27 super(context, attrs);
28 init();
29 }
30
31 public SwitchView(Context context, AttributeSet attrs, int defStyle) {
32 super(context, attrs, defStyle);
33 init();
34 }
35
36 //1 初始化图片(加载)
37 private void init() {
38 Resources resr = getResources();
39 mSwitch_on = BitmapFactory.decodeResource(resr, R.mipmap.switch_on);
40 mSwitch_off = BitmapFactory.decodeResource(resr, R.mipmap.switch_off);
41 mSwitch_circle = BitmapFactory.decodeResource(resr, R.mipmap.switch_circle);
42 setOnTouchListener(this);
43 }
44
45 //2 设置控件宽高(测量)
46 @Override
47 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
48 int widthSize = mSwitch_off.getWidth();
49 int heightSize = mSwitch_off.getHeight();
50 max = mSwitch_off.getWidth() - mSwitch_circle.getWidth();
51 setMeasuredDimension(widthSize, heightSize);
52 }
53
54 //3 布局(排版)
55 @Override
56 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
57 super.onLayout(changed, left, top, right, bottom);
58 }
59
60 //4 最后绘制控件
61 @Override
62 protected void onDraw(Canvas canvas) {
63 super.onDraw(canvas);
64 Matrix m = new Matrix();
65 Paint p = new Paint();
66 if (mCurrentState) {
67 canvas.drawBitmap(mSwitch_on, m, p);
68 } else {
69 canvas.drawBitmap(mSwitch_off, m, p);
70 }
71 canvas.drawBitmap(mSwitch_circle, left, 0, p);
72 }
73
74 //5 触摸事件
75 @Override
76 public boolean onTouch(View v, MotionEvent event) {
77 switch (event.getAction()) {
78 case MotionEvent.ACTION_DOWN:
79 downX = (int) event.getX();//初始X轴按下坐标
80 break;
81 case MotionEvent.ACTION_MOVE:
82 moveX = (int) event.getX();
83 left = moveX - downX;
84 if (!mCurrentState) {
85 //关闭状态边界处理
86 if (left < 0) {
87 left = 0;
88 } else if (left > max) {
89 left = max;
90 }
91 } else {
92 //开启状态边界处理
93 left = moveX - downX;
94 if (left > 0) {//向右滑
95 left = max;
96 } else if (Math.abs(left) > max) {
97 left = 0;
98 } else {
99 left = max - Math.abs(left);
100 }
101 }
102 break;
103 case MotionEvent.ACTION_UP:
104 case MotionEvent.ACTION_CANCEL://抬起时的判断
105 int upX = (int) event.getX();
106 boolean state = false; //滑动是否成功
107 //1 关闭状态
108 if (!mCurrentState) {
109 //滑动是否成功
110 //a 移动距离超过 1/2 的滑动宽度
111 //b 触摸点在滑动区域,开启按钮
112 state = (moveX - downX) >= max / 2 || upX >= max;
113 if (state) {
114 left = max;
115 mCurrentState = true;
116 } else {
117 left = 0;
118 }
119 } else {
120 //2 开启状态,判断滑动是否成功
121 //a 移动距离超过 1/2 的滑动宽度
122 //b 触摸点在滑动区域,关闭按钮
123 state = (downX - moveX) >= max / 2 || upX <= max;
124 if (state) {
125 left = 0;
126 mCurrentState = false;
127 } else {
128 left = max;
129 }
130 }
131 //滑动成功 且 回调接口不能空 触发回调方法
132 if (state && null != mOnSwitchChangedListener) {
133 mOnSwitchChangedListener.onSwitchChanged(mCurrentState);
134 }
135 break;
136 }
137 invalidate();
138 return true;
139 }
140
141 //开关切换回调接口
142 public interface OnSwitchChangedListener {
143 void onSwitchChanged(boolean isOpen);
144 }
145
146 public void setOnSwitchChangedListener(OnSwitchChangedListener listener) {
147 this.mOnSwitchChangedListener = listener;
148 }
149
150 public void setCurrentState(boolean isOpen) {
151 mCurrentState = isOpen;
152 left = isOpen ? max : 0;
153 invalidate();
154 }
155
156 }