android自定义滑块解锁,自定义滑动解锁View

先写出自定义View界面

代码如下:先创建一个View继承View,然后重写测量方法去测量出要显示的真是高度,再重写绘制方法,去把这个按钮绘制在什么位置。然后就是为我们后续的触摸事件做准备,重写OnTouchEvent()

package com.example.z.selfscrollunlock;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.support.annotation.Nullable;

import android.util.AttributeSet;

import android.view.MotionEvent;

import android.view.View;

/**

* Created by z on 2017/11/25.

*/

public class SelfUnLockView extends View {

private Bitmap mBitmap;

private int mHeight;

private int mWidth;

private Paint mPaint;

private int mWidth1;

public SelfUnLockView(Context context) {

this(context, null);

}

public SelfUnLockView(Context context, @Nullable AttributeSet attrs) {

super(context, attrs);

mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.switch_button);

mHeight = mBitmap.getHeight();

mWidth = mBitmap.getWidth();

mPaint = new Paint();

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

mWidth1 = MeasureSpec.makeMeasureSpec(widthMeasureSpec, MeasureSpec.EXACTLY);

setMeasuredDimension(mWidth1, mHeight);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

canvas.drawBitmap(mBitmap, 0, 0, mPaint);

}

@Override

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

float rawX = event.getRawX();

//当我手指触摸到滑块时候,滑块过来要移动这个点减去滑块一般的长度 raw

float moveX = rawX - mWidth / 2;

scrollTo((int) -moveX,0);

break;

case MotionEvent.ACTION_MOVE:

break;

case MotionEvent.ACTION_UP:

break;

}

return super.onTouchEvent(event);

}

}

在自定义View 的构造方法中,我们去初始化一个画笔,初始化背景的 长 宽。在onTouch()中,处理触摸事件,在手指按下的时候,让滑块中间位置移动到触摸点:注意,这个ScrollTo方法,往右边移动是减去一个数,可以想成,水调用这个Scroll方法,是this ,当前自定义View。你简单记忆成这个移动是移动他的爹,滑块向右移动,你就当成是滑块不动,他爹应该是往那边移动才是我们想要的结果,他爹是往左边移动才行。我们的左边是右边正,往左了肯定是负。效果如下:

但是很多问题,比如越界问题,回弹等,我们一步一步处理

处理点击滑块外部不响应

把这个滑动事件判断一下执行:

if (rawX > 0 && rawX < mWidth) {

scrollTo((int) -moveX, 0);

}

处理左边越界问题

更改一个地方:

if (rawX > mWidth/2 && rawX < mWidth) {

处理滑块滑动

在ontouch事件的move 动作中处理:并处理滑动越界问题

case MotionEvent.ACTION_MOVE:

//处理越界问题

float rawXMove = event.getRawX();//

if(rawXMove >mWidth/2 && rawXMove <=getMeasuredWidth()-mWidth/2){

float dexX = rawXMove - mWidth/2; //变化量

scrollTo((int) ( - dexX), 0);

}

break;

注意上面的滑动越界问题,我是通过手指的位置判断的,当然你可以通过一个增加量来判断是否满足条件,如果满足不满足条件直接把偏移量置零或者最大 。注意上面的判断有个细节,我使用的是getMeasuredWidth( ) 来处理,并不是用的mWidth1,如果你是用后者,你会发现这个值非常大。会越界。这里的getMeasuredWidth()拿的值就是控件背景宽度。如果弄不明白就直接使用增加量判断

你的滑块是否能滑动呢?

如果你的滑块能点击,不能滑动,注意看你的自定义控件是否消费事件,如果没有消费事件,就是掉super方法,肯定不会处理,所以你要返回值改为true.消费时间才行,因为滑动事件和点击事件不同的!

滑块的回原点

case MotionEvent.ACTION_UP:

float endRawX = event.getRawX();

if(endRawX

scrollTo(0,0);

}else {

Toast.makeText(getContext(),"解锁成功",Toast.LENGTH_LONG).show();

}

解锁不成功,缓慢回弹

1.创建Scroller对象

2.调用startScroll 方法去滚动 ,配置滚动信息

3.出发重新绘制调用 invalidate();

4.计算滚动的偏移量。重写computerScroll( ) ,根据当前已过时间计算偏移量 返回的是boolean值,如果没结束,就是滚动还没有结束, scroller.scrollTo(X,getcriiX(),0)然后出发绘制,完整代码如下:

package com.example.z.selfscrollunlock;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.support.annotation.Nullable;

import android.util.AttributeSet;

import android.view.MotionEvent;

import android.view.View;

import android.widget.Scroller;

import android.widget.Toast;

/**

* Created by z on 2017/11/25.

*/

public class SelfUnLockView extends View {

private Bitmap mBitmap;

private int mHeight;

private int mWidth;

private Paint mPaint;

private int mWidth1;

private float mRawX;

private Scroller mScroller;

private ScrollListener mListener;

public SelfUnLockView(Context context) {

this(context, null);

}

public SelfUnLockView(Context context, @Nullable AttributeSet attrs) {

super(context, attrs);

mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.switch_button);

mHeight = mBitmap.getHeight();

mWidth = mBitmap.getWidth();

mPaint = new Paint();

mScroller = new Scroller(getContext());

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

mWidth1 = MeasureSpec.makeMeasureSpec(widthMeasureSpec, MeasureSpec.EXACTLY);

setMeasuredDimension(mWidth1, mHeight);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

canvas.drawBitmap(mBitmap, 0, 0, mPaint);

}

@Override

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

mRawX = event.getRawX();

//当我手指触摸到滑块时候,滑块过来要移动这个点减去滑块一般的长度 raw

float moveX = mRawX - mWidth / 2;

if (mRawX > mWidth / 2 && mRawX < mWidth) {

scrollTo((int) -moveX, 0);

}

break;

case MotionEvent.ACTION_MOVE:

//处理越界问题

float rawXMove = event.getRawX();//

if(rawXMove >mWidth/2 && rawXMove <=getMeasuredWidth()-mWidth/2){

float dexX = rawXMove - mWidth/2; //变化量

scrollTo((int) ( - dexX), 0);

}

break;

case MotionEvent.ACTION_UP:

float endRawX = event.getRawX();

if(endRawX

/* mScroller.startScroll(getScrollX(),0,0-getScrollX(),0,500); //配置滚动信息

// invalidate();

// scrollTo(0,0);*/

int startX = getScrollX();//滚动开始时滚动偏移量

int startY = 0;

int endX = 0;//滚动最终位置的滚动偏移量

int dx = endX - startX;//滚动偏移量的变化量

int dy =0;

int duration = 1500;//滚动时长

//step2:配置滚动的成员变量

mScroller.startScroll(startX, startY, dx, dy, duration);

invalidate();//step3:触发重新绘制

}else {

Toast.makeText(getContext(),"解锁成功",Toast.LENGTH_LONG).show();

/** 出发接口方法*/

if(mListener != null){

mListener.onScrollunLock();

}

}

break;

}

return true;

}

@Override

public void computeScroll() {

if(mScroller.computeScrollOffset()){

scrollTo(mScroller.getCurrX(),0);

invalidate();

}

}

/**

* 回调函数

*/

public interface ScrollListener{

void onScrollunLock();

}

/**

* 宫外不调用的方法

*/

public void onScrollViewMethed(ScrollListener l){

this.mListener = l;

}

}

测滑菜单

需求分析:

1.继承Viewgroup

2.测量布局孩子

3.处理越界问题

package com.example.z.selfscrollunlock;

import android.content.Context;

import android.util.AttributeSet;

import android.view.MotionEvent;

import android.view.View;

import android.view.ViewGroup;

/**

* Created by z on 2017/11/25.

*/

public class SlidingMenu extends ViewGroup {

private float mRawX;

private View mRight;

private View mLeft;

private int mMeasuredWidth;

private int mMeasuredWidth1;

public SlidingMenu(Context context) {

this(context, null);

}

public SlidingMenu(Context context, AttributeSet attrs) {

super(context, attrs);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

measureChildren(widthMeasureSpec, heightMeasureSpec);

}

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

mLeft = getChildAt(0);

mRight = getChildAt(1);

mMeasuredWidth = mLeft.getMeasuredWidth();

mMeasuredWidth1 = mRight.getMeasuredWidth();

int measuredHeight = mLeft.getMeasuredHeight();

int measuredHeight1 = mRight.getMeasuredHeight();

mLeft.layout(-mMeasuredWidth, 0, 0, measuredHeight);

mRight.layout(0, 0, mMeasuredWidth1, measuredHeight1);

}

@Override

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

mRawX = event.getRawX();

break;

case MotionEvent.ACTION_MOVE:

float rawX1 = event.getRawX();

float v = -rawX1 + mRawX; //滚动偏移量

float finall = v + getScrollX(); //最终偏移量

if(finall >0){

scrollTo(0,0);

}else {

scrollTo(-mMeasuredWidth,0);

}

return true;

//

// int i = mMeasuredWidth1 - mMeasuredWidth;

// if (v

// v = i;

// }

// else if (v < -mMeasuredWidth) {

// v = 0;

// }

scrollTo((int) -v, 0);

// scrollBy((int) -v, 0);

// mRawX = rawX1;

}

return true;

}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值