实例介绍
【实例截图】
【核心代码】
package com.lewis.customerview;
import com.lewis.slipbutton.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.View.OnTouchListener;
public class SlipButton extends View implements OnTouchListener {
public static final String TAG = "SlipButton";
// 开关开启时的背景,关闭时的背景,滑动按钮
private Bitmap slipImg;
//the background of the slip button
private Bitmap bg;
private Bitmap slipBubble;
private Matrix matrix = new Matrix();
private Paint paint = new Paint();
// 滑动按钮的左边坐标
private float leftPosOfSlipImg;
//the middle value of the slip image,note: its not the half of the
//slip image width,its the place where to show the slip on or off
//so its smaller than the half of the slip image
private int slipOnEndPos = 0;
private int slipOffStartPos = 0;
private int bgWidth = 0;
private Rect on_Rect;
private Rect off_Rect;
private Rect src_Rect;
private Rect dst_Rect;
// 是否正在滑动
private boolean isSlipping = false;
// 当前开关状态,true为开启,false为关闭
private boolean isSwitchOn = false;
// 手指按下时的水平坐标X,当前的水平坐标X
private float previousX, currentX;
// 开关监听器
private OnSwitchListener onSwitchListener;
// 是否设置了开关监听器
private boolean isSwitchListenerOn = false;
private VelocityTracker mVelocityTracker;
private static final int SNAP_VELOCITY = 100;
public SlipButton(Context context) {
super(context);
init();
}
public SlipButton(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.SlipButton);
boolean isOn = a.getBoolean(R.styleable.SlipButton_slipOn, false);
int count = a.getIndexCount();
//get the specified recourse id in xml file
int bgId = 0;
int slipBtId = 0;
for(int i = 0;i < count; i ) {
int attr = a.getIndex(i);
switch(attr) {
case R.styleable.SlipButton_bg:
bgId = a.getResourceId(attr, 0);
break;
case R.styleable.SlipButton_slipImg:
slipBtId = a.getResourceId(attr, 0);
break;
}
}
a.recycle();
//decode the image defined in xml file
setImageRes(bgId, slipBtId);
setSwitchState(isOn);
init();
}
/**
* set touch listener
*/
private void init() {
setOnTouchListener(this);
}
public void setImageRes(int bgId, int slipId){
bg = BitmapFactory.decodeResource(getResources(),bgId);
slipImg = BitmapFactory.decodeResource(getResources(), slipId);
slipBubble = BitmapFactory.decodeResource(getResources(),R.drawable.sb_slip_bubble);
bgWidth = bg.getWidth();
//The end position of the switch on state
//25 is the value which half of slip image add to the bubble's right side
slipOnEndPos = slipImg.getWidth()/2 slipBubble.getWidth()/2;
//The start position of the switch off state
slipOffStartPos = slipImg.getWidth()/2 - slipBubble.getWidth()/2;
on_Rect = new Rect(0, 0,slipOnEndPos, slipImg.getHeight());
off_Rect = new Rect(slipOffStartPos, 0, slipImg.getWidth(), slipImg.getHeight());
src_Rect = new Rect(0, 0, bg.getWidth(), slipImg.getHeight());
dst_Rect = new Rect(0, 0, bg.getWidth(), bg.getHeight());
//this method should be called to initialize the rect state
setDrawImgRect();
}
public void setSwitchState(boolean switchState) {
isSwitchOn = switchState;
if (isSwitchListenerOn) {
onSwitchListener.onSwitched(isSwitchOn);
}
//reset the draw rect
setDrawImgRect();
//redraw the view
invalidate();
}
public boolean getSwitchState() {
return isSwitchOn;
}
public void updateSwitchState(boolean switchState) {
isSwitchOn = switchState;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(slipImg, src_Rect, dst_Rect, paint);
canvas.drawBitmap(bg, matrix, paint);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(bg.getWidth(),
bg.getHeight());
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(event);
boolean isUpAlreadyCatch = false;
boolean previousState = false;
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
currentX = event.getX();
previousState = isSwitchOn;
//check whether need change the state of the switch
changeSwitchState(event.getX());
if (isSwitchListenerOn && (previousState != isSwitchOn)) {
onSwitchListener.onSwitched(isSwitchOn);
}
break;
case MotionEvent.ACTION_DOWN:
if (event.getX() > bg.getWidth() || event.getY() > bg.getHeight()) {
return false;
}
isSlipping = true;
previousX = event.getX();
currentX = previousX;
break;
case MotionEvent.ACTION_UP:
//catch up motion, the default should not change the state of the switch
isUpAlreadyCatch = true;
previousState = isSwitchOn;
changeSwitchState(event.getX());
default:
do {
if (isUpAlreadyCatch) {
break;
}
//when not catch the up motion, check the state of the switch by the move speed of the touch
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000);
int velocityX = (int) velocityTracker.getXVelocity();
previousState = isSwitchOn;
//when the move speed greater than the specified speed, we consider it has a state change
if (velocityX > SNAP_VELOCITY) {
isSwitchOn = true;
break;
}
if (velocityX < -SNAP_VELOCITY) {
isSwitchOn = false;
break;
}
} while (false);
isSlipping = false;
//call the listener
if (isSwitchListenerOn && (previousState != isSwitchOn)) {
onSwitchListener.onSwitched(isSwitchOn);
}
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
}
//reset the draw rect
setDrawImgRect();
//redraw the view
invalidate();
return true;
}
private void changeSwitchState(float currentPos) {
if (currentPos >= (bgWidth / 2)) {
isSwitchOn = true;
} else {
isSwitchOn = false;
}
}
private void setDrawImgRect(){
do{
//when slipping, calculator the left position of the slip image to be drawn
if(isSlipping) {
if (currentX > bgWidth) {
leftPosOfSlipImg = on_Rect.left;
} else {
leftPosOfSlipImg = slipOffStartPos - currentX;
}
}
if(isSlipping && leftPosOfSlipImg >= 0 && leftPosOfSlipImg <= bgWidth){
break;
}
//need reset the position of the slip image
if(isSwitchOn) {
leftPosOfSlipImg = on_Rect.left;
}else {
leftPosOfSlipImg = off_Rect.left;
}
}while(false);
int srcLeft = (int) leftPosOfSlipImg;
src_Rect.left = srcLeft;
src_Rect.right = srcLeft bgWidth;
}
public void setOnSwitchListener(OnSwitchListener listener) {
onSwitchListener = listener;
isSwitchListenerOn = true;
}
public interface OnSwitchListener {
abstract void onSwitched(boolean isSwitchOn);
}
}
标签: 滑动
相关软件
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论