public class LockView extends View {
private Bitmap button;
private int buttonHeight;
private Paint paint;
private int buttonWidth;
private float downX;
private int viewW;
private Scroller scroller;//帮助scroll的工具类
private OnLockListener onLockListener;
public LockView(Context context) {
this(context, null);
}
public LockView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public LockView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//加载滑块的图片
button = BitmapFactory.decodeResource(getResources(), R.drawable.switch_button);
buttonHeight = button.getHeight();
buttonWidth = button.getWidth();
//创建画笔
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
//1.创建scroller
scroller = new Scroller(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//手动设置当前view的高度为滑块的高度
setMeasuredDimension(widthMeasureSpec, buttonHeight);
//获取当前view测量的宽度
// int measuredWidth = getMeasuredWidth();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画滑块按钮
canvas.drawBitmap(button, 0, 0, paint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = event.getX();
//滑块需要移动的距离
float offsetX = -(downX - buttonWidth / 2);
//当点击在button之外时 不处理手势事件
if (downX > buttonWidth) {
return false;
}
//只有在手指触摸到button宽度一半之后才进行处理
if (downX >= buttonWidth / 2) {
//将滑块移动到制定位置
scrollTo((int) offsetX, 0);
}
break;
case MotionEvent.ACTION_MOVE:
//获取当前x
float moveX = event.getX();
//scrollby
// float moveOffsetX = moveX- downX;
//滑动偏移
float scrollX = -(moveX - buttonWidth / 2);
//判断左边界是否出界
if (moveX < buttonWidth / 2) {
scrollX = 0;
} else if (moveX > viewW - buttonWidth / 2) {//判断右边是否越界
scrollX = -(viewW - buttonWidth);
}
scrollTo((int) scrollX, 0);
break;
case MotionEvent.ACTION_UP:
float upX = event.getX();
int thresX = viewW - buttonWidth / 2;
if (upX < thresX) {
//复位
// scrollTo(0,0);
int startX = getScrollX();//获取x方向上的偏移
int startY = 0;//在y方向上的偏移
int dx = -startX;
int dy=0;
//2.开始滑动 只是做了各个时间点需要滑动到的位置
scroller.startScroll(startX,startY,dx,dy);
//3.
invalidate();//重新绘制
} else {
//解锁
if(onLockListener!=null){
onLockListener.onLock();
}
}
break;
}
return true;//消费掉事件
}
//4.使用scroller需要复写这个方法
@Override
public void computeScroll() {
super.computeScroll();
//判断当前还需不需要继续滑动 true 需要 false 不需要
if(scroller.computeScrollOffset()){
scrollTo(scroller.getCurrX(),0);//scroller.getCurrX()当前需要滑动到的位置偏移
invalidate();//继续进行滑动
// ViewCompat.postInvalidateOnAnimation(this);//invalidate在有些模拟器上的兼容
}
}
/**
* view布局改变后执行 layout-setFrame-sizechanged-onSizechanged
*
* @param w
* @param h
* @param oldw
* @param oldh
*/
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
viewW = w;
}
public interface OnLockListener{
void onLock();
}
public void setOnLockListener(OnLockListener onLockListener){
this.onLockListener = onLockListener;
}
}
自定义控件练习——滑动解锁
最新推荐文章于 2022-06-28 15:33:38 发布