Android自定义开关
来源:互联网 发布:淘宝笔记本排行榜 编辑:程序博客网 时间:2024/06/15 23:13
最近在学习自定义view,感觉写业务代码对技术的提高实在有限,就琢磨每天 必须要多学点东西了,我的规划是自定义view、jni,之后再往framework层走,先拓展技术栈,再精进。
不多说先看效果图
一:需求分析:首先我们来明确一下需求,有两种方式来控制这个开关,一种是点击,即可切换开关,另一种是通过滑动来控制,这样比起我们一般情况下直接用个图片选择器体验会好一些。
二:实现思路:其实思路还是很清晰的,大的步骤的话就两步
1:将view绘制出来,其实是两张图片,一张是开关的背景,在上面有一个滑块,滑块在最左侧时为关闭状态,在最右侧时为打开的状态。
2:给view设置点击事件和滑动事件,逻辑还是比较清晰的,当点击时开关的状态切换,当滑动时,根据滑动的位置来确定当前应该是开的状态还是关的状态
三:代码分析:
代码分为三个部分:初始化、绘制,点击及触摸事件处理
- 一 :初始化,代码如下
/** * 注意构造方法,一个参数用于实例化,两个参数用于在布局文件中使用时调用,三个用于自定义style时使用,这里我们用两个参数的 * * @param context */ public MyToggleButton(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public void init(Context context) { paint = new Paint(); paint.setAntiAlias(true); backgroundBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.switch_background); slidingBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.slide_button); maxLeft = backgroundBitmap.getWidth() - slidingBitmap.getWidth(); //设置点击事件 setOnClickListener(this); }
- 二:绘制流程:onMeasure方法,用于测量控件的宽高,onLayout用于摆放控件的位置,一般自定义的viewGroup才用得到onDraw方法,将控件在屏幕中绘制出来,这里我们只用得到onMeasure和onDraw,代码如下:
/** * 指定view的大小 * * @param widthMeasureSpec * @param heightMeasureSpec */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(backgroundBitmap.getWidth(), backgroundBitmap.getHeight()); } /** * 具体的绘制方法 * * @param canvas */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawBitmap(backgroundBitmap, 0, 0, paint); canvas.drawBitmap(slidingBitmap, slideLeft, 0, paint); }
- 三:点击及触摸事件的处理,事件完成之后要调用 invalidate()方法,会导致onDraw方法重新执行,今儿从新绘制view,具体代码如下:
/** * 点击事件方法的具体实现 * * @param v */ @Override public void onClick(View v) { if (isClickEnable) { isOpen = !isOpen; flushView(isOpen); } } /** * 滑动事件的具体实现 * * @param event * @return */ @Override public boolean onTouchEvent(MotionEvent event) { //执行父类的方法,否则,onclick点击方法就不起作用 super.onTouchEvent(event); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: initX = startX = (int) event.getX(); isClickEnable=true; break; case MotionEvent.ACTION_MOVE: endX = (int) event.getX(); lastX = (endX - startX); slideLeft += lastX; if (slideLeft > maxLeft) { slideLeft = maxLeft; } else if (slideLeft < 0) { slideLeft = 0; } invalidate(); startX = (int) event.getX(); if (Math.abs(endX - initX) > 5) { isClickEnable = false; } break; case MotionEvent.ACTION_UP: if (!isClickEnable) { if (slideLeft > maxLeft / 2) { isOpen = true; } else { isOpen = false; } flushView(isOpen); invalidate(); } break; } return true; } /** * 刷新控件,归位,是开还是关 */ public void flushView(boolean isOpen) { if (isOpen) { slideLeft = maxLeft; } else { slideLeft = 0; } invalidate(); }
完整代码如下:
/** * Created by ${HMC} on 2017/4/4.实现的效果就是点击或者滑动都可以对开关进行控制 * 自定义view的绘制流程: * 首先走构造方法,然后如下 * ①:onMeasure方法,用于测量控件的宽高 * ②onLayout用于摆放控件的位置,一般自定义的viewGroup才用得到 * ③onDraw方法,将控件在屏幕中绘制出来 * <p> * 思路:先将view绘制出来,在做逻辑处理,比如滑动等 */public class MyToggleButton extends View implements View.OnClickListener { Bitmap backgroundBitmap; Bitmap slidingBitmap; Paint paint; private int slideLeft; private int maxLeft; //滑动时的坐标记录 int startX; int endX; //移动的距离 int lastX; //最开始的距离 int initX; //开关是否打开 boolean isOpen; //点击事件是否可用 boolean isClickEnable = true; /** * 两个用于在布局文件中使用时调用,三个用于自定义style时使用 * * @param context */ public MyToggleButton(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public void init(Context context) { paint = new Paint(); paint.setAntiAlias(true); backgroundBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.switch_background); slidingBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.slide_button); maxLeft = backgroundBitmap.getWidth() - slidingBitmap.getWidth(); //设置点击事件 setOnClickListener(this); } /** * 指定view的大小 * * @param widthMeasureSpec * @param heightMeasureSpec */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(backgroundBitmap.getWidth(), backgroundBitmap.getHeight()); } /** * 具体的绘制方法 * * @param canvas */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawBitmap(backgroundBitmap, 0, 0, paint); canvas.drawBitmap(slidingBitmap, slideLeft, 0, paint); } /** * 点击事件方法的具体实现 * * @param v */ @Override public void onClick(View v) { if (isClickEnable) { isOpen = !isOpen; flushView(isOpen); } } /** * 滑动事件的具体实现 * * @param event * @return */ @Override public boolean onTouchEvent(MotionEvent event) { //执行父类的方法,否则,onclick点击方法就不起作用 super.onTouchEvent(event); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: initX = startX = (int) event.getX(); isClickEnable=true; break; case MotionEvent.ACTION_MOVE: endX = (int) event.getX(); lastX = (endX - startX); slideLeft += lastX; if (slideLeft > maxLeft) { slideLeft = maxLeft; } else if (slideLeft < 0) { slideLeft = 0; } invalidate(); startX = (int) event.getX(); if (Math.abs(endX - initX) > 5) { isClickEnable = false; } break; case MotionEvent.ACTION_UP: if (!isClickEnable) { if (slideLeft > maxLeft / 2) { isOpen = true; } else { isOpen = false; } flushView(isOpen); invalidate(); } break; } return true; }
0 0
- Android自定义开关按钮
- android 自定义开关按钮
- android自定义开关
- Android 自定义开关控件
- android自定义开关控件
- Android 自定义开关控件
- Android自定义Switch开关
- Android自定义开关按钮
- Android自定义开关3
- <Android>自定义Log开关
- android自定义开关SwitchView
- android 自定义开关
- android自定义滑动开关
- android 自定义开关按钮
- Android自定义开关
- Android自定义开关
- android自定义开关控件-SlideSwitch
- android自定义状态开关-modeswitch
- 三数和为零
- 可变参数列表源码的剖析
- linux基础小知识(2)--语句
- 追忆计算机之父艾伦图灵:在一个时刻两次改变历史的人
- 集电极开路
- Android自定义开关
- 数据结构:单链表(四)
- C# WinForm控件之Dock先后顺序调整
- VS2010使用大漠插件
- C++ string类中的字符串查找
- 对AsyncTask的深入了解
- 用Java实现计算器
- spring7
- C++远征之封装篇——常对象成员、常成员函数