本文来自作者:If_
, 链接:https://juejin.im/post/5ec33c616fb9a0432b2704f0
正文
说到滑动解锁,就回到了2012~2014年,iPhone4S、5、5S年代,如今准备踏入2020年,这些年国产机崛起,再也不是公交车上都是iPhone4S的场景。本篇来使用ViewDragHelper实现滑动解锁。
成品展示
先来分析一下页面的元素
- 背景图
- 圆角滑道
- 圆形滑块
- 闪动提示文字
其他一些细节:
- 滑道和圆形滑块之间有些边距,我们使用padding来处理。
我们需要自定义的就是第2点,这个滑道包含一个滑块的图片和提示文字,滑块使用原生ImageView即可,而提示文字则是一个支持渐变着色的TextView(不是重点)。
渐变着色的TextView
先秒掉简单的,渐变着色的TextView
,不是重点,代码量不多。
public class ShineTextView extends TextView {
private LinearGradient mLinearGradient;
private Matrix mGradientMatrix;
private int mViewWidth = 0;
private int mTranslate = 0;
public ShineTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (mViewWidth == 0) {
mViewWidth = getMeasuredWidth();
if (mViewWidth > 0) {
Paint paint = getPaint();
mLinearGradient = new LinearGradient(0,
0,
mViewWidth,
0,
new int[]{getCurrentTextColor(), 0xffffffff, getCurrentTextColor()},
null,
Shader.TileMode.CLAMP);
paint.setShader(mLinearGradient);
mGradientMatrix = new Matrix();
}
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mGradientMatrix != null) {
mTranslate += mViewWidth / 5;
if (mTranslate > 2 * mViewWidth) {
mTranslate = -mViewWidth;
}
mGradientMatrix.setTranslate(mTranslate, 0);
mLinearGradient.setLocalMatrix(mGradientMatrix);
//每80毫秒执行onDraw()
postInvalidateDelayed(80);
}
}
}
下面重点介绍我们使用ViewDragHelper实现拽托、滑动的滑道View:SlideLockView
让滑块滑动起来
滑道实际就是一个FrameLayout,我们使用ViewDragHelper将滑块ImageView进行拽托,主要我们要做以下几件事:
1、限制拽托的左侧起点、右侧终点(否则滑块就出去啦!)
2、松手时判断滑块的x坐标是偏向滑道的左侧还是右侧,来决定滑动到起点还是终点。
3、滚动结束,判断是否到达了右侧的终点。
4、判断拽托速度,如果超过指定速度,则自动滚动滑块到右侧终点。
看到这4点,如果让我们用事件分发来处理,代码量和判断会非常多,并且需要做速度检测,而使用ViewDragHelper
,上面4点都封装好啦,我们添加一个回调,再将事件委托给它,在回调中做事情上面4点的处理,一切都简单起来了。
创建SlideLockView
,继承FrameLayout
public class SlideLockView extends FrameLayout {
/**
* 拽托帮助类
*/
private ViewDragHelper mViewDragHelper;
public SlideLockView(@NonNull Context context) {
this(context, null);
}
public SlideLockView(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public SlideLockView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
private void init(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
//进行初始化...
}
}
创建ViewDragHelper,使用create
静态方法创建,有3个参数,第一个拽托控件的父控件(就是当前View),第二个参数是拽托灵敏度,数值越大,越灵敏,默认为1.0,第三个参数为回调对象。
private void init(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleA