自定义控件

自定义控件一般的几个步骤:
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 }
原文地址:https://www.cnblogs.com/suiyilaile/p/9014152.html