自定义控件一般的几个步骤:
1.初始化相关背景图片,布局文件,自定义属性
2.设置控件宽高OnMeasure()
3.布局或者排版OnLayout()
4.绘制控件OnDraw()
5.处理触摸事件OnTouchEvent()
 public class SwitchView extends View implements View.OnTouchListener {

     //开关状态图片
private Bitmap mSwitch_on, mSwitch_off, mSwitch_circle; //开关状态 默认关闭
private boolean mCurrentState = false; //开关切换回调接口
private OnSwitchChangedListener mOnSwitchChangedListener; //X轴按下坐标
private int downX;
//X轴移动时触点坐标
private int moveX;
//X轴偏移量
private int left = 0;
//最大可移动距离
private int max; public SwitchView(Context context) {
super(context);
init();
} public SwitchView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
} public SwitchView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
} //1 初始化图片(加载)
private void init() {
Resources resr = getResources();
mSwitch_on = BitmapFactory.decodeResource(resr, R.mipmap.switch_on);
mSwitch_off = BitmapFactory.decodeResource(resr, R.mipmap.switch_off);
mSwitch_circle = BitmapFactory.decodeResource(resr, R.mipmap.switch_circle);
setOnTouchListener(this);
} //2 设置控件宽高(测量)
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = mSwitch_off.getWidth();
int heightSize = mSwitch_off.getHeight();
max = mSwitch_off.getWidth() - mSwitch_circle.getWidth();
setMeasuredDimension(widthSize, heightSize);
} //3 布局(排版)
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
} //4 最后绘制控件
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Matrix m = new Matrix();
Paint p = new Paint();
if (mCurrentState) {
canvas.drawBitmap(mSwitch_on, m, p);
} else {
canvas.drawBitmap(mSwitch_off, m, p);
}
canvas.drawBitmap(mSwitch_circle, left, 0, p);
} //5 触摸事件
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = (int) event.getX();//初始X轴按下坐标
break;
case MotionEvent.ACTION_MOVE:
moveX = (int) event.getX();
left = moveX - downX;
if (!mCurrentState) {
//关闭状态边界处理
if (left < 0) {
left = 0;
} else if (left > max) {
left = max;
}
} else {
//开启状态边界处理
left = moveX - downX;
if (left > 0) {//向右滑
left = max;
} else if (Math.abs(left) > max) {
left = 0;
} else {
left = max - Math.abs(left);
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL://抬起时的判断
int upX = (int) event.getX();
boolean state = false; //滑动是否成功
//1 关闭状态
if (!mCurrentState) {
//滑动是否成功
//a 移动距离超过 1/2 的滑动宽度
//b 触摸点在滑动区域,开启按钮
state = (moveX - downX) >= max / 2 || upX >= max;
if (state) {
left = max;
mCurrentState = true;
} else {
left = 0;
}
} else {
//2 开启状态,判断滑动是否成功
//a 移动距离超过 1/2 的滑动宽度
//b 触摸点在滑动区域,关闭按钮
state = (downX - moveX) >= max / 2 || upX <= max;
if (state) {
left = 0;
mCurrentState = false;
} else {
left = max;
}
}
//滑动成功 且 回调接口不能空 触发回调方法
if (state && null != mOnSwitchChangedListener) {
mOnSwitchChangedListener.onSwitchChanged(mCurrentState);
}
break;
}
invalidate();
return true;
} //开关切换回调接口
public interface OnSwitchChangedListener {
void onSwitchChanged(boolean isOpen);
} public void setOnSwitchChangedListener(OnSwitchChangedListener listener) {
this.mOnSwitchChangedListener = listener;
} public void setCurrentState(boolean isOpen) {
mCurrentState = isOpen;
left = isOpen ? max : 0;
invalidate();
} }

自定义控件 - 切换开关:SwitchView的更多相关文章

  1. Qt之自定义控件(开关按钮)

    简述 接触过IOS系统的童鞋们应该对开关按钮很熟悉,在设置里面经常遇到,切换时候的滑动效果比较帅气. 通常说的开关按钮,有两个状态:on.off. 下面,我们利用自定义控件来实现一个开关按钮. 简述 ...

  2. android自定义控件——以滑动开关为例

    0.引言 (1)Android从4.0开始提供了switch的滑动开关效果组件,但是之前版本却没有 (2)很多时候我们写程序,都希望把有用的通用的通用的东西封装起来,以便以后重用. 本文根据组件开发思 ...

  3. android自定义控件一站式入门

    自定义控件 Android系统提供了一系列UI相关的类来帮助我们构造app的界面,以及完成交互的处理. 一般的,所有可以在窗口中被展示的UI对象类型,最终都是继承自View的类,这包括展示最终内容的非 ...

  4. ASP.NET MVC学习之母版页和自定义控件的使用

    一.母板页_Layout.cshtml类似于传统WebForm中的.master文件,起到页面整体框架重用的目地1.母板页代码预览 <!DOCTYPE html> <html> ...

  5. C# 自定义控件VS用户控件

    1 自定义控件与用户控件区别 WinForm中, 用户控件(User Control):继承自 UserControl,主要用于开发 Container 控件,Container控件可以添加其他Con ...

  6. 自定义控件之 圆形 / 圆角 ImageView

    一.问题在哪里? 问题来源于app开发中一个很常见的场景——用户头像要展示成圆的:       二.怎么搞? 机智的我,第一想法就是,切一张中间圆形透明.四周与底色相同.尺寸与头像相同的蒙板图片,盖在 ...

  7. 如何开发FineReport的自定义控件?

    FineReport作为插件化开发的报表软件,有些特殊需求的功能需要自己开发,开发的插件包帆软官方有提提供,可以去帆软论坛上找,本文将主要介绍如何开发一个自定义控件,这里讲讲方法论. 第一步:实例化一 ...

  8. WPF自定义控件第二 - 转盘按钮控件

    继之前那个控件,又做了一个原理差不多的控件.这个控件主要模仿百度贴吧WP版帖子浏览界面左下角那个弹出的按钮盘.希望对大家有帮助. 这个控件和之前的也差不多,为了不让大家白看,文章最后发干货. 由于这个 ...

  9. 【Win 10应用开发】AdaptiveTrigger在自定义控件中是可以触发的

    前些天,看到有网友给我留言,说AdaptiveTrigger在自定义控件(模板化控件)中不能触发.因为当时我正在写其他的代码,就没有去做实验来验证,于是我就给这位网友提了使用GotoVisualSta ...

随机推荐

  1. MyBatis逆向工程无效

    在Taget目录下修改的东西无法逆向, 在源代码目录就可以

  2. pathlib模块替代os.path

    pathlib模块替代os.path 在Python 3.4之前和路径相关操作函数都放在os模块里面,尤其是os.path这个子模块,可以说os.path模块非常常用.而在Python 3.4,标准库 ...

  3. PHP批量导入excell表格到mysql数据库

    PHP批量导入excell表格到mysql数据库,本人通过亲自测试,在这里分享给大家 1,下载 php  excell类库 网上搜索可以下载,这里不写地址 2,建html文件 <form met ...

  4. 【LGR-063】洛谷11月月赛 I & MtOI2019 Ex Div.2 (A-C)

    [MtOI2019]黑蚊子多 : 按题意模拟 #include<iostream> #include<cstdio> #include<cstring> using ...

  5. Neo4j源代码分析

    1.下载neo4j源码 https://github.com/neo4j/neo4j/ 参考文章 原文地址:https://blog.csdn.net/e15273/article/details/7 ...

  6. MySQL 5.7原生通用二进制格式安装包安装过程

    目录 官方文档 文件说明 官方文档 https://dev.mysql.com/doc/refman/5.7/en/binary-installation.html 文件说明 Directory Co ...

  7. 神经风格转换Neural Style Transfer a review

    原文:http://mp.weixin.qq.com/s/t_jknoYuyAM9fu6CI8OdNw 作者:Yongcheng Jing 等 机器之心编译 风格迁移是近来人工智能领域内的一个热门研究 ...

  8. [跨界思考|瑞典|IKEA]有意思的宜家|IKEA

    来自北欧瑞典的IKEA无疑是成功的企业.根据我最近几天的去宜家的体验和来自网上的资料,我发现IKEA不止是成功的企业,而且可以说是一家独特又伟大的公司. 说到IKEA,就不得不说下它的创始人:坎普拉德 ...

  9. SpringCloud学习系列-SpringCloud

    SpringCloud是什么? SpringCloud=分布式微服务架构下的一站式解决方案,是各个微服务架构落地技术的集合体,俗称微服务全家桶 SpringCloud,基于SpringBoot提供了一 ...

  10. 数据结构--排序--快排and冒泡(python)

    听说大厂面试,限时两分钟写出来快排... 闲着没事,写了一下... def Partition(L,low,high): pivotkey = L[low] while low<high: wh ...