博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自定义控件 - 切换开关:SwitchView
阅读量:5019 次
发布时间:2019-06-12

本文共 5432 字,大约阅读时间需要 18 分钟。

自定义控件一般的几个步骤: 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

你可能感兴趣的文章
python 中的 sys , os 模块用法总结
查看>>
解题:国家集训队 Middle
查看>>
响应者链
查看>>
指针从函数内部带回返回值
查看>>
在使用webView播放flash或视频文件时无法关闭声音的问题
查看>>
redhat 7 源码安装 mysql5.5.49
查看>>
CCP浅谈
查看>>
NAT虚拟网络配置
查看>>
c#部分---需要实例化的内容;
查看>>
销售类
查看>>
技术项目,问题
查看>>
线程池总结
查看>>
Learning to rank (software, datasets)
查看>>
git常见问题
查看>>
.NETFramework:template
查看>>
杂项:MySQL
查看>>
HTML5 介绍
查看>>
Linux tomcat+JDK 安装配置
查看>>
题解 poj3585 Accumulation Degree (树形dp)(二次扫描和换根法)
查看>>
php post接口,登录功能
查看>>