1.示意图

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemltbzIwMTM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" width="300" height="60" alt="">      

2.自己定义控件SwitchView

public class SwitchView extends View {
public static final String TAG = SwitchView.class.getSimpleName(); // 状态
public static final int STATUS_OFF = 0;
public static final int STATUS_ON = 1;
public static final int STATUS_SCROLING = 2; // 用于显示的文本
private String mOnText = "打开";
private String mOffText = "关闭"; private int mSwitchStatus = STATUS_OFF;
private boolean mHasScrolled = false;// 表示是否发生过滚动 private int mSrcX = 0, mDstX = 0;
private int mBmpWidth = 0;
private int mBmpHeight = 0;
private int mThumbWidth = 0; private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private OnSwitchChangedListener mOnSwitchChangedListener = null;
// 开关状态图
Bitmap mSwitch_off, mSwitch_on, mSwitch_thumb; public SwitchView(Context context) {
this(context, null);
} public SwitchView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
} public SwitchView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
} // 初始化三幅图片
private void init() {
Resources res = getResources();
mSwitch_off = BitmapFactory.decodeResource(res, R.drawable.bg_switch_off);
mSwitch_on = BitmapFactory.decodeResource(res, R.drawable.bg_switch_on);
mSwitch_thumb = BitmapFactory.decodeResource(res, R.drawable.switch_thumb);
mBmpWidth = mSwitch_on.getWidth();
mBmpHeight = mSwitch_on.getHeight();
mThumbWidth = mSwitch_thumb.getWidth();
} @Override
public void setLayoutParams(LayoutParams params) {
params.width = mBmpWidth;
params.height = mBmpHeight;
super.setLayoutParams(params);
} /**
* 设置监听器
*
*/
public void setOnSwitchChangedListener(OnSwitchChangedListener l) {
mOnSwitchChangedListener = l;
} /**
* 设置文本
*/
public void setText(final String onText, final String offText) {
mOnText = onText;
mOffText = offText;
invalidate();
} /**
* 设置开关的状态
*/
public void setStatus(boolean on) {
mSwitchStatus = (on ? STATUS_ON : STATUS_OFF);
} @Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
mSrcX = (int) event.getX();
break;
case MotionEvent.ACTION_MOVE:
mDstX = Math.max((int) event.getX(), 10);
mDstX = Math.min(mDstX, 62);
if (mSrcX == mDstX)
return true;
mHasScrolled = true;
AnimationTransRunnable aTransRunnable = new AnimationTransRunnable(mSrcX, mDstX, 0);
new Thread(aTransRunnable).start();
mSrcX = mDstX;
break;
case MotionEvent.ACTION_UP:
if (mHasScrolled == false) {// 假设没有发生过滑动,就意味着这是一次单击过程
mSwitchStatus = Math.abs(mSwitchStatus - 1);
int xFrom = 10, xTo = 62;
if (mSwitchStatus == STATUS_OFF) {
xFrom = 62;
xTo = 10;
}
AnimationTransRunnable runnable = new AnimationTransRunnable(xFrom, xTo, 1);
new Thread(runnable).start();
} else {
invalidate();
mHasScrolled = false;
}
// 状态改变的时候 回调事件函数
if (mOnSwitchChangedListener != null) {
mOnSwitchChangedListener.onSwitchChanged(this, mSwitchStatus);
}
break; default:
break;
}
return true;
} @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 画图的时候 内部用到了一些数值的硬编码,事实上不太好,
// 主要是考虑到图片的原因,图片周围有透明边界,所以要有一定的偏移
// 硬编码的数值仅仅要看懂了代码,事实上能够理解其含义,能够做对应改进。 mPaint.setTextSize(14);
mPaint.setTypeface(Typeface.DEFAULT_BOLD); if (mSwitchStatus == STATUS_OFF) {
drawBitmap(canvas, null, null, mSwitch_off);
drawBitmap(canvas, null, null, mSwitch_thumb);
mPaint.setColor(Color.rgb(105, 105, 105));
canvas.translate(mSwitch_thumb.getWidth(), 0);
canvas.drawText(mOffText, 0, 20, mPaint);
} else if (mSwitchStatus == STATUS_ON) {
drawBitmap(canvas, null, null, mSwitch_on);
int count = canvas.save();
canvas.translate(mSwitch_on.getWidth() - mSwitch_thumb.getWidth(), 0);
drawBitmap(canvas, null, null, mSwitch_thumb);
mPaint.setColor(Color.WHITE);
canvas.restoreToCount(count);
canvas.drawText(mOnText, 17, 20, mPaint);
} else { // SWITCH_SCROLING
mSwitchStatus = mDstX > 35 ? STATUS_ON : STATUS_OFF;
drawBitmap(canvas, new Rect(0, 0, mDstX, mBmpHeight), new Rect(0, 0, (int) mDstX, mBmpHeight), mSwitch_on);
mPaint.setColor(Color.WHITE);
canvas.drawText(mOnText, 17, 20, mPaint); int count = canvas.save();
canvas.translate(mDstX, 0);
drawBitmap(canvas, new Rect(mDstX, 0, mBmpWidth, mBmpHeight),
new Rect(0, 0, mBmpWidth - mDstX, mBmpHeight), mSwitch_off);
canvas.restoreToCount(count); count = canvas.save();
canvas.clipRect(mDstX, 0, mBmpWidth, mBmpHeight);
canvas.translate(mThumbWidth, 0);
mPaint.setColor(Color.rgb(105, 105, 105));
canvas.drawText(mOffText, 0, 20, mPaint);
canvas.restoreToCount(count); count = canvas.save();
canvas.translate(mDstX - mThumbWidth / 2, 0);
drawBitmap(canvas, null, null, mSwitch_thumb);
canvas.restoreToCount(count);
} } public void drawBitmap(Canvas canvas, Rect src, Rect dst, Bitmap bitmap) {
dst = (dst == null ? new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()) : dst);
Paint paint = new Paint();
canvas.drawBitmap(bitmap, src, dst, paint);
} /**
* AnimationTransRunnable 做滑动动画所使用的线程
*/
private class AnimationTransRunnable implements Runnable {
private int srcX, dstX;
private int duration; public AnimationTransRunnable(float srcX, float dstX, final int duration) {
this.srcX = (int) srcX;
this.dstX = (int) dstX;
this.duration = duration;
} @Override
public void run() {
final int patch = (dstX > srcX ? 5 : -5);
if (duration == 0) {
SwitchView.this.mSwitchStatus = STATUS_SCROLING;
SwitchView.this.postInvalidate();
} else {
int x = srcX + patch;
while (Math.abs(x - dstX) > 5) {
mDstX = x;
SwitchView.this.mSwitchStatus = STATUS_SCROLING;
SwitchView.this.postInvalidate();
x += patch;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
mDstX = dstX;
SwitchView.this.mSwitchStatus = mDstX > 35 ? STATUS_ON : STATUS_OFF;
SwitchView.this.postInvalidate();
}
} } public static interface OnSwitchChangedListener {
public abstract void onSwitchChanged(SwitchView obj, int status);
}
}

3.源代码下载

http://download.csdn.net/detail/strawberry2013/7309871

Android_自己定义切换控件SwitchView的更多相关文章

  1. MUI框架-03-自定义MUI控件样式

    MUI框架-03-自定义MUI控件样式 开发请查阅:官方文档:http://dev.dcloud.net.cn/mui/ui/ 如何自定义MUI控件样式 mui 以 iOS 7的 UI 为基础,补充了 ...

  2. Xamarin自定义布局系列——PivotPage,多页面切换控件

    PivotPage ---- 多页面切换控件 PivotPage是一个多页面切换控件,类似安卓中的ViewPager和UWP中的Pivot枢轴控件. 起初打算直接通过ScrollView+StackL ...

  3. android:自己定义组合控件Weight(高仿猫眼底部菜单条)

    在我们实际开发其中.会碰见一些布局结构类似或者同样的界面.比如应用的设置界面.tabbutton界面等. 这时候.对于刚開始学习的人来说,xml里面一个个绘制出来也许是最初的想法.可能随着经验的积累, ...

  4. Android 使用shape定义不同控件的的颜色、背景色、边框色

    Android 使用shape定义不同控件的的颜色.背景色.边框色 设置按钮的右边框和底边框颜色为红色,边框大小为3dp: 在drawable新建一个 buttonstyle.xml的文件,内容如下: ...

  5. Quartz2D-二维画图引擎 、自己定义UI控件

    // // MyDraw.m // 绘图 #import "MyDraw.h" @implementation MyDraw //Quartz2D 是一个二维绘图引擎 //自己定义 ...

  6. android 自己定义组合控件

    自己定义控件是一些android程序猿感觉非常难攻破的难点,起码对我来说是这种,可是我们能够在网上找一些好的博客关于自己定义控件好好拿过来学习研究下,多练,多写点也能找到感觉,把一些原理弄懂,今天就讲 ...

  7. delphi Table切换控件顺序问题

    delphi Table切换控件顺序问题 Tagorder的值就是确定Table键切换顺序的 以上做法只能解决同一类型的多个控件(如Edit1,edit2....)显示顺序问题 假如有不同类型的控件如 ...

  8. ImageSwitch图像切换控件

    ImageSwitch图像切换控件 继承ViewAnimator所以可以做动画 继承ViewGroup所以可以装别的控件,所以ImageSwitch里面装的就是image,不过要找个ImageView ...

  9. android自己定义开关控件

    近日在android项目要使用开关控件.可是android中自带的开关控件不太惬意,所以就打算通过自己定义View写一个开关控件 ios的开关控件当然就是我要仿照的目标. 先上图:   waterma ...

随机推荐

  1. Wordpress入门笔记

    简单介绍一下wordpress个人操作,建议安装中文版. 登入后台管理者页面, 浏览器地址栏输入           (线上) http://XXXX.com/wp-login.php (本地) ht ...

  2. 大数据学习——spark-steaming学习

    官网http://spark.apache.org/docs/latest/streaming-programming-guide.html 1.1.  用Spark Streaming实现实时Wor ...

  3. day01_11.break和continue

    1.continue 下一个(用next更加形象一点)整体的循环没有被破坏掉,而是跳到下一个循环单位中 <?php for($i=1;$i<=10;$i++){ if($i==4){ co ...

  4. 序列化 pickle & json & shelve

    把内存数据转成字符,叫序列化,dump,dumps 把字符转成内存数据类型,叫反序列化load,loads dumps:仅转成字符串 dump不仅能把对象转换成str,还能直接存到文件内 json.d ...

  5. postgres 用户管理

    首次安装完成 pg 数据库后,会默认自带一个用户, 用户名: postgres 密码: postgres 可以使用命令 \du 查看数据库用户 创建新用户: create user dev with ...

  6. 对python的想法

    作为计算机专业的学生,在编程语言之余,我认为掌握一门脚本语言是很必要的.尤其是现在在数据分析,AI,机器学习等各个方面都大放异彩的python.相比于之前接触过的Java,C,C++乃至于php等语言 ...

  7. math & 三元一次方程组的解法

    math & 三元一次方程组的解法 class 6 math 例题 问题: 1. 已经做好的与没有做好的比例是 5 比 7; 2 再做好51,完成总数的 70%; 3. 问,一共要做多少朵花? ...

  8. 【bzoj1040】[ZJOI2008]骑士 并查集+基环树dp

    题目描述 Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火绵延五百里,在 ...

  9. 【bzoj4026】dC Loves Number Theory 可持久化线段树

    题目描述 dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯竭的水题资源.  给定一个长度为 n的正整数序列A,有q次询问,每次询问一段区间内所有元素乘积的φ(φ(n ...

  10. BZOJ-1221 软件开发

    这题是基于一道经典的费用流模型. 将每天拆成两个点i和j,新增源和汇并建立六种边: 1.从源出发到每个i点,flow为+∞,cost为每条新餐巾的价值,表示这一天所使用的餐巾中来自购买的餐巾 2.从源 ...