自定义控件一般的几个步骤:
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. Django、Flask、Tornado的区别?

    Django:Python 界最全能的 web 开发框架,battery-include 各种功能完备,可维护性和开发速度一级棒.常有人说 Django 慢,其实主要慢在 Django ORM 与数据 ...

  2. ECMAScript 6 学习笔记(一)

    ECMAScript 6简介 ECMAScript 6.0(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了.它的目标,是使得JavaScript语言可以用来编写 ...

  3. Restful,SAOP,SOA,RPC的基础理解

    什么是Restful restful是一种架构设计风格,提供了设计原则和约束条件,而不是架构.而满足这些约束条件和原则的应用程序或设计就是 RESTful架构或服务. 主要的设计原则: 资源与URI ...

  4. HTML-图片和多媒体

    1.图片和多媒体 (1)    图片:img元素 src 属性:图片路径: alt 属性:图片无法显示时使用的替代文字: title:鼠标悬停时显示的文字 : <img src="图片 ...

  5. 39. Combination Sum (Java)

    Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), fin ...

  6. 利用 TCMalloc 优化 Nginx 的性能

    TCMalloc 全称为 Thread-Caching Malloc,是谷歌的开源工具 google-perftools 的成员,它可以 在内存分配效率和速度上高很多,可以很大程度提高服务器在高并发情 ...

  7. Educational Codeforces Round 32 Maximum Subsequence CodeForces - 888E (meet-in-the-middle,二分,枚举)

    You are given an array a consisting of n integers, and additionally an integer m. You have to choose ...

  8. Python----公开课

    # 构造函数- 类在实例化的时候,执行一些基础性的初始化的工作- 使用特殊的名称和写法- 在实例化的时候自动执行- 是在实例化的时候第一个被执行的函数- ----------------------- ...

  9. LeetCode--617--合并二叉树(python)

    给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠. 你需要将他们合并为一个新的二叉树.合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 ...

  10. webstorm 点击右上角运行run 启动vue项目

    点击右上角框 -> 编辑结构 点击加号 新增一个npm项目 前提:node环境已经安装完成,npm包管理器 1.进行定位到项目的路径2.安装依赖包,npm install3.启动服务,npm r ...