自定义控件一般的几个步骤:
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. c++构造顺序

    1. 静态成员最先构造,按照静态成员初始化顺序,不是类里面的声明顺序 2. 父类构造 3. 非静态成员构造,按照类成员声明顺序,不是逗号初始化成员顺序 4. 自身构造函数 Demo: class Te ...

  2. UESTC-1057 秋实大哥与花(线段树+成段加减+区间求和)

    秋实大哥与花 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit St ...

  3. ECCV2014 Accepted paper

    今天早上看到小伙伴们说ECCV2014结果出来了, 自己于是赶紧看了下, 感觉ECCV2014显著性的文章和以往的不太一样. 1.Salient Montages from Unconstrained ...

  4. npm学习(一)之安装、更新以及管理npm版本

    安装npm 安装前须知: npm是在Node中编写的,因此需要安装Node.js才能使用npm.可以通过Node.js网站安装npm,或者安装节点版本管理器NVM. 如果只是想开始探索npm,使用No ...

  5. 使用PHPWord生成word文档

    有时我们需要把网页内容保存为Word文档格式,以供其他人员查看和编辑.PHPWord是一个用纯PHP编写的库,使用PHPWord可以轻松处理word文档内容,生成你想要的word文档. 下载源码 安装 ...

  6. 04-Django-templates

    # 模板系统 - 模板:一组相同或者相似的页面,在需要个性化的地方进行留白,需要的时候只是用数据填充就可以使用 - 步骤: 1. 在settings中进行设置:TEMPLATES 2. 在tmeplt ...

  7. 自定义ajax函数(仿照jQuery)

    AJAX介绍 AJAX = 异步 JavaScript 和 XML. 全称:Asynchronous Javascript And XML: AJAX 是一种用于创建快速动态网页的技术. 通过在后台与 ...

  8. 出现( linker command failed with exit code 1)错误总结(http://blog.csdn.net/hengshujiyi/article/details/21182813)

    这种问题,通常出现在添加第三方库文件或者多人开发时. 这种问题一般是找不到文件而导致的链接错误. 我们可以从如下几个方面着手排查. 1.以如下错误为例,如果是多人开发,你同步完成后发现出现如下的错误. ...

  9. Spring基础02——Spring HelloWorld

    1.首先我们来创建一个HelloWorld类,通过Spring来对这个类进行实例化 package com.wzy.lesson1; /** * @author wzy * @version 1.0 ...

  10. 15.Linux-CentOS系统重启网卡ping不通问题(云环境)

    问题: CentOS系统网络不通,重启网卡后能ping通,等一会就又不通. 解决: 在云环境管理平台下,KVM系统的MAC地址,使其重新生成一下.