可滑动的ToggleButton(开关)
2013-12-28 17:25:01
网上看到一篇关于可滑动的ToogleButton的文章,有代码,觉得挺好,但是不符合我的要求,因此在他的代码基础上改了一些。(作者看到了勿喷啊,实在找不到原文了,只好把代码下载地址贴出来。)
源码下载地址: http://download.csdn.net/detail/zshq280017423/4240703
先来两张效果图:
然后上代码:
最主要的类是SlipButton.java
package com.util; import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener; import com.view.SlipButton.R; public class SlipButton extends View implements OnTouchListener { private float DownX, NowX;// 按下时的x,当前的x
private float btn_on_left = ;
private float btn_off_left = ; private boolean NowChoose = false;// 记录当前按钮是否打开,true为打开,flase为关闭
private boolean isChecked;
private boolean OnSlip = false;// 记录用户是否在滑动的变量
private boolean isChgLsnOn = false; private OnChangedListener ChgLsn;
private Bitmap bg_on;
private Bitmap bg_off;
private Bitmap slip_btn; public SlipButton(Context context) {
super(context);
init();
} public SlipButton(Context context, AttributeSet attrs) {
super(context, attrs);
init();
} private void init() { // 初始化
bg_on = BitmapFactory.decodeResource(getResources(),
R.drawable.split_left_1);
bg_off = BitmapFactory.decodeResource(getResources(),
R.drawable.split_right_1);
slip_btn = BitmapFactory.decodeResource(getResources(),
R.drawable.split_1); btn_off_left = bg_off.getWidth() - slip_btn.getWidth(); setOnTouchListener(this); // 设置监听器,也可以直接复写OnTouchEvent
} @Override
protected void onDraw(Canvas canvas) {// 绘图函数
super.onDraw(canvas); Matrix matrix = new Matrix();
Paint paint = new Paint();
float x; if (NowX < (bg_on.getWidth() / )) { // 滑动到前半段与后半段的背景不同,在此做判断
x = NowX - slip_btn.getWidth() / ;
canvas.drawBitmap(bg_off, matrix, paint);// 画出关闭时的背景
} else {
x = bg_on.getWidth() - slip_btn.getWidth() / ;
canvas.drawBitmap(bg_on, matrix, paint);// 画出打开时的背景
} if (OnSlip) {// 是否是在滑动状态,
if (NowX >= bg_on.getWidth()) {// 是否划出指定范围,不能让游标跑到外头,必须做这个判断
x = bg_on.getWidth() - slip_btn.getWidth() / ;// 减去游标1/2的长度...
} else if (NowX < ) {
x = ;
} else {
x = NowX - slip_btn.getWidth() / ;
}
} else {// 非滑动状态
if (NowChoose) {// 根据现在的开关状态设置画游标的位置
x = btn_off_left;
canvas.drawBitmap(bg_on, matrix, paint);// 初始状态为true时应该画出打开状态图片
} else {
x = btn_on_left;
}
}
if (isChecked) {
canvas.drawBitmap(bg_on, matrix, paint);
x = btn_off_left;
isChecked = !isChecked;
} if (x < ) {// 对游标位置进行异常判断...
x = ;
} else if (x > bg_on.getWidth() - slip_btn.getWidth()) {
x = bg_on.getWidth() - slip_btn.getWidth();
}
canvas.drawBitmap(slip_btn, x, , paint);// 画出游标. } public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {// 根据动作来执行代码
case MotionEvent.ACTION_DOWN:// 按下
if (event.getX() > bg_on.getWidth()
|| event.getY() > bg_on.getHeight()) {
return false;
}
OnSlip = true;
DownX = event.getX();
NowX = DownX;
break; case MotionEvent.ACTION_MOVE:// 滑动
Log.d("David", "event.getX = " + event.getX());
Log.d("David", "event.getY = " + event.getY());
NowX = event.getX();
boolean LastChoose = NowChoose; if (NowX >= (bg_on.getWidth() / )) {
NowChoose = true;
} else {
NowChoose = false;
} if (isChgLsnOn && (LastChoose != NowChoose)) { // 如果设置了监听器,就调用其方法..
ChgLsn.OnChanged(NowChoose);
}
break; case MotionEvent.ACTION_UP:// 松开
OnSlip = false;
break;
default:
}
invalidate();// 重画控件
return true;
} public void SetOnChangedListener(OnChangedListener l) {// 设置监听器,当状态修改的时候
isChgLsnOn = true;
ChgLsn = l;
} public interface OnChangedListener {
abstract void OnChanged(boolean CheckState);
} public void setCheck(boolean isChecked) {
this.isChecked = isChecked;
NowChoose = isChecked;
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int measuredHeight = measureHeight(heightMeasureSpec);
int measuredWidth = measureWidth(widthMeasureSpec);
setMeasuredDimension(measuredWidth, measuredHeight);
} private int measureHeight(int measureSpec) { /*int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec); // Default size if no limits are specified. int result = 500;
if (specMode == MeasureSpec.AT_MOST){
// Calculate the ideal size of your
// control within this maximum size.
// If your control fills the available
// space return the outer bound. result = specSize;
} else if (specMode == MeasureSpec.EXACTLY){
// If your control can fit within these bounds return that value.
result = specSize;
}*/
return bg_on.getHeight();
} private int measureWidth(int measureSpec) { /*int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec); // Default size if no limits are specified.
int result = 500;
if (specMode == MeasureSpec.AT_MOST){
// Calculate the ideal size of your control
// within this maximum size.
// If your control fills the available space
// return the outer bound.
result = specSize;
} else if (specMode == MeasureSpec.EXACTLY){
// If your control can fit within these bounds return that value.
result = specSize;
}*/
return bg_on.getWidth();
}
}
代码比较简单,而且注释比较详细。
说一些几个问题:
1. onTouch()方法中得到的event.getX()和event.getY()是什么值?取值范围是多少?
刚开始我以为不管咱们的SlipButton放在什么位置,得到的event.getX()值因该是相对屏幕的坐标值,~~其实是错误的,event.getX()只有你的触摸点在当前SlipButton view的布局范围之内才会取到值的。但是值的范围可不仅仅是你的SlipButton view的大小哦,因为一旦你的触摸点在view范围之内触摸到,那么触摸点就可以移到View之外的任何地方了,所以取值范围应该是全屏哦,因此我们在代码里做了如下判断:
if (event.getX() > bg_on.getWidth()
|| event.getY() > bg_on.getHeight()) {
return false;
}
2. measureWidth()和measureHeight()为什么会返回一个固定值?
首先根据用途,我们自定义的SlipButton View根本没有必要去由调用者调整大小,因为这个ToggleButton本身就是起到开关作用的,在应用中应该是一致的,所以我让这两个方法返回固定值。关于onMeasure()方法根详细的描述,请看我的另一篇文章:http://www.cnblogs.com/wlrhnh/p/3479928.html
下载源码,请猛戳这里。
可滑动的ToggleButton(开关)的更多相关文章
- ToggleButton开关状态按钮控件
ToggleButton开关状态按钮控件 一.简介 1. 2.ToggleButton类结构 父类是CompoundButton,引包的时候注意下 二.ToggleButton开关状态按钮控件使用方法 ...
- OpenCV学习笔记——滑动条开关
由于opencv库中并没有专门为开关而设的函数,可以用滑动条做开关 代码: #include<highgui.h> #include<cv.h> int g_switch_va ...
- iOS:步进UIStepper、滑动块UISlider、开关UISwitch的基本使用
步进UIStepper.滑动块UISlider:当它们作为事件,被触发时,它们的值会发生改变.正因为如此,触发该事件时,可以一张一张翻阅浏览图片,,,, 步进UIStepper: @property( ...
- 绘制 ToggleButton --重写view
package com.example.compoundbuttonview.view; import com.example.compoundbuttonview.R; import android ...
- 自定义View-6 状态按钮 滑动 点击
View public class SwitchButton extends View implements OnClickListener, OnTouchListener { privat ...
- iOS7下滑动返回与ScrollView共存二三事
[转载请注明出处] = =不是整篇复制就算注明出处了亲... iOS7下滑动返回与ScrollView共存二三事 [前情回顾] 去年的时候,写了这篇帖子iOS7滑动返回.文中提到,对于多页面结构的应用 ...
- Ext 6.5.3 classic版本,自定义实现togglefield开关控件
1,在Ext 6.5.3的classic版中没有提供开关控件,参照modern版中 togglefield开关的实现,继承滑动器(sliderfield),自定义一个开关按钮.支持value绑定和点击 ...
- Android控件ToggleButton的使用方法
ToggleButton(开关button)是Android系统中比較简单的一个组件,是一个具有选中和未选择状态双状态的button.而且须要为不同的状态设置不同的显示文本. ToggleButton ...
- 转--2014年最新810多套android源码2.46GB免费一次性打包下载
转载自:http://www.eoeandroid.com/thread-497046-1-1.html 感谢该博客主人无私奉献~~ 下面的源码是从今年3月份开始不断整理源码区和其他网站上的安卓例子源 ...
随机推荐
- (一)二维数组&&指针数组与数组指针
一.首先我们从字面意思理解一下什么是指针数组什么是数组指针 1.指针数组:本质是一个数组,数组中的每一个元素是一个指针. 2.数组指针:本质是一个指针,而指针指向一个数组. 二.我们该怎么区分指针数组 ...
- 【Todo】蒙特卡洛(蒙特卡罗)树 & 卷积网络
https://www.zhihu.com/question/41176911/answer/90066752 这里面有关于Deep Learning和蒙特卡洛树的一些内容 https://www.z ...
- mysql 命令行快速导出数据,导入数据
如果数据有20几万以上的时候,下面的方法很实用 导出数据 1.into outfile select * from table into outfile 'C:/a.sql'; 2.mysqldump ...
- 反射-优化及程序集等(用委托的方式调用需要反射调用的方法(或者属性、字段),而不去使用Invoke方法)
反射-优化及程序集等(用委托的方式调用需要反射调用的方法(或者属性.字段),而不去使用Invoke方法) 创建Delegate (1).Delegate.CreateDelegate(Type, ...
- VB6 GDI+ 入门教程[2] GDI+初始化
http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[2] GDI+初始化 2009 年 6 月 18 日 7 ...
- Element can be click when out of view
WebDriver can't action the element when out of view Webdriver can't action the element when the elem ...
- 使用node js 操作 Mysql 数据库
使用node js 操作 Mysql 数据库 http://www.nodejs.org/ //node js 数据库操作 MySQL //使用https://github.com/felixge/n ...
- mysql 免安装版本 命令安装
1.down load mysql-5.5.28-win32.zip 2.unzip it to a path such as d:/mysq/mysql-5.5.28-win32 3.copy th ...
- noip2016题解汇总
[uoj#260]玩具谜题 传送门 http://uoj.ac/problem/260 分析 模拟. int n,m; int dir[N]; char nam[N][L]; int a[M],s[M ...
- Linq分页查询
//Linq分页查询 int pageIndex = Convert.ToInt32(HttpContext.Current.Request["PageIndex"]); int ...