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(开关)的更多相关文章

  1. ToggleButton开关状态按钮控件

    ToggleButton开关状态按钮控件 一.简介 1. 2.ToggleButton类结构 父类是CompoundButton,引包的时候注意下 二.ToggleButton开关状态按钮控件使用方法 ...

  2. OpenCV学习笔记——滑动条开关

    由于opencv库中并没有专门为开关而设的函数,可以用滑动条做开关 代码: #include<highgui.h> #include<cv.h> int g_switch_va ...

  3. iOS:步进UIStepper、滑动块UISlider、开关UISwitch的基本使用

    步进UIStepper.滑动块UISlider:当它们作为事件,被触发时,它们的值会发生改变.正因为如此,触发该事件时,可以一张一张翻阅浏览图片,,,, 步进UIStepper: @property( ...

  4. 绘制 ToggleButton --重写view

    package com.example.compoundbuttonview.view; import com.example.compoundbuttonview.R; import android ...

  5. 自定义View-6 状态按钮 滑动 点击

    View public class SwitchButton extends View implements OnClickListener, OnTouchListener {     privat ...

  6. iOS7下滑动返回与ScrollView共存二三事

    [转载请注明出处] = =不是整篇复制就算注明出处了亲... iOS7下滑动返回与ScrollView共存二三事 [前情回顾] 去年的时候,写了这篇帖子iOS7滑动返回.文中提到,对于多页面结构的应用 ...

  7. Ext 6.5.3 classic版本,自定义实现togglefield开关控件

    1,在Ext 6.5.3的classic版中没有提供开关控件,参照modern版中 togglefield开关的实现,继承滑动器(sliderfield),自定义一个开关按钮.支持value绑定和点击 ...

  8. Android控件ToggleButton的使用方法

    ToggleButton(开关button)是Android系统中比較简单的一个组件,是一个具有选中和未选择状态双状态的button.而且须要为不同的状态设置不同的显示文本. ToggleButton ...

  9. 转--2014年最新810多套android源码2.46GB免费一次性打包下载

    转载自:http://www.eoeandroid.com/thread-497046-1-1.html 感谢该博客主人无私奉献~~ 下面的源码是从今年3月份开始不断整理源码区和其他网站上的安卓例子源 ...

随机推荐

  1. (一)stm32之CMSIS标准、库目录、GPIO

    一.CMSIS标准 ST公司的stm32采用的是cortex-m3内核,内核是整个微处理器的CPU.该内核是ARM公司设计的一种处理器体系架构.内核与外设的关系就像PC上的CPU与硬盘.主板.内存等的 ...

  2. hdu_3555 bomb

    数位动态规划     数位动态规划是求解一个大区间[L, R]中间满足条件Q的所有数字的个数(或者和,或其他)的一种方法.它通过分析每一位上的数字,一般用 dp[len][digit][...] 来表 ...

  3. php ajax json jquery 记录

    php+jquery+ajax+json简单小例子 <html> <title>php+jquery+ajax+json简单小例子</title> <?php ...

  4. 小韦XP 和win2003装电信天翼3G无线上网卡

    拷贝文件.bat @echo 开始注册echo n|copy /-y msports.dll %windir%\system32\regsvr32 /s %windir%\system32\mspor ...

  5. 【EasyX】RGB to Gray

    code: #include <graphics.h> #include <conio.h> void main() { initgraph(, ); // 读取图片 load ...

  6. python 练习 5

    #!/usr/bin/python # -*- coding: utf-8 -*- from collections import deque def z69(): '''猜牌术(1) 魔术师,最上面 ...

  7. Ubuntu下配置和编译cpp-ethereum客户端

    Ethereum,中文翻译是“以太坊”,是一个公有区块链的开源项目.因为以太坊是基于P2P网络所以没有中心节点,所以用户仅安装Ethereum客户端即可连入Ethereum公共网络或者在自己的test ...

  8. hdu------(3549)Flow Problem(最大流(水体))

    Flow Problem Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tota ...

  9. FireFox 一键清理缓存

    https://addons.mozilla.org/zh-CN/firefox/addon/empty-cache-button/

  10. C#.web 打开PDF

    转自:http://blog.163.com/red_guitar@126/blog/static/11720612820112483221665/ string fileName = "2 ...