自定义一个Switch

package com.example.testdefine;


import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;


public class MyView extends View {


private Paint mPaint =new Paint(Paint.ANTI_ALIAS_FLAG);
public static final String TAG = "SlideSwitch";
 public static final int SWITCH_OFF = 0;//关闭状态
 public static final int SWITCH_ON = 1;//打开状态
 public static final int SWITCH_SCROLING = 2;//滚动状态
 
 //用于显示的文本
 private String mOnText = "打开";
 private String mOffText = "关闭";


 private int mSwitchStatus = SWITCH_OFF;


 private boolean mHasScrolled = false;//表示是否发生过滚动
 private int mSrcX = 0, mDstX = 0;
 
 private int mBmpWidth = 0;
 private int mBmpHeight = 0;
 private int mThumbWidth = 0;
 
 Bitmap mSwitch_off, mSwitch_on, mSwitch_thumb;
 private OnSwitchChangedListener mOnSwitchChangedListener = null;
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// TODO Auto-generated constructor stub
init();
}


public MyView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}


public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint();
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.my_view);
int textColor = array.getColor(R.styleable.my_view_myview_textcolor, 0XFF00FF00);
mPaint.setColor(textColor);
array.recycle();
init();
}

public 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) {
// TODO Auto-generated method stub
super.setLayoutParams(params);
params.width = mBmpWidth;
params.height = mBmpHeight;
}

public void setOnSwitchChangedListener(
OnSwitchChangedListener onSwitchChangedListener) {
mOnSwitchChangedListener = onSwitchChangedListener;
}


public void setText(final String onText, final String offText) {
mOnText = onText;
mOffText = offText;
invalidate();
}

public void setStatus(boolean on) {
mSwitchStatus = (on ? SWITCH_ON : SWITCH_OFF);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
Log.d(TAG, "onTouchEvent  x=" + event.getX());
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 == SWITCH_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 onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
// TODO Auto-generated method stub
super.onLayout(changed, left, top, right, bottom);
}

@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
mPaint.setTextSize(14);
mPaint.setTypeface(Typeface.DEFAULT_BOLD);


if (mSwitchStatus == SWITCH_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 == SWITCH_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 ? SWITCH_ON : SWITCH_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;


/**
* 滑动动画

* @param srcX
*            滑动起始点
* @param dstX
*            滑动终止点
* @param duration
*            是否采用动画,1采用,0不采用
*/
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) {
MyView.this.mSwitchStatus = SWITCH_SCROLING;
MyView.this.postInvalidate();
} else {
Log.d(TAG, "start Animation: [ " + srcX + " , " + dstX + " ]");
int x = srcX + patch;
while (Math.abs(x - dstX) > 5) {
mDstX = x;
MyView.this.mSwitchStatus = SWITCH_SCROLING;
MyView.this.postInvalidate();
x += patch;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
mDstX = dstX;
MyView.this.mSwitchStatus = mDstX > 35 ? SWITCH_ON
: SWITCH_OFF;
MyView.this.postInvalidate();
}
}


}


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值