Android 自己动手实现滑动九宫格解锁
文章主要以实现思路为主。来带领大家逐步实现该效果功能.如有问题,请多多提出
效果预览
整体思路分析
九宫格滑动解锁,为当下比较热门的手机,Pad等触屏设备很常见的设备解锁操作。其主要是以九 宫格按钮通过滑动链接各个按钮,并达到解锁的一种方式。操作简单快捷。
我在此处的实现方式是通过自定义View进行实现的。所以在开发中大概以一下思路进行处理:
1. 九宫格按键参数生成
2. 绘制九宫格
3. 处理控件触摸事件
4. 对应事件回调处理
开始进行
此处没有什么鬼,就是一样的操作,并主要重写View 的 onMeasure,onLayout 和onDraw三个 方法,之后会付上对应的下载地址
逐步实现
所谓的九宫格,无非是九个按钮。而按钮,在控件当中的定位无非就是九个矩形而已。所以我们需要 生成对应的创建对应的按钮位置信息
创建按钮参数实体,用于保存按钮参数信息
此处我使用了私有的匿名内部类
/**
*按钮信息参数
**/
private class keys {
int radius;
Rect bound; // 详细位置信息
boolean isSelect = false;
//构造方法,用于快速构建实体信息
public keys(Rect bound, int radius) {
this.bound = bound;
this.radius = radius;
}
}
在onLayout方法当中进行构建按钮.
private keys keys[]; //按钮
/**
* 构建按按钮基本信息
*/
private void generateKeyView() {
keys = new keys[keyNumber * keyNumber];//keyNumber 为 按键数量边距,会决定按键总数量
int KeyLayoutSize; //按键布局大小
boolean isHorizontal; //布局均衡方向
int rightBoundary; //布局右边界
if (getWidth() > getHeight()) {
isHorizontal = false;
KeyLayoutSize = getHeight();
} else {
isHorizontal = true;
KeyLayoutSize = getWidth();
}
int keySize = KeyLayoutSize / keyNumber; //按键大小
confirmSize = keySize / 3; //触摸确定距离为 按钮大小的三分之一
defaultRadius = keySize / 3;
Point pointStart; // 按钮起始点(左上角坐标)
if (isHorizontal) {
pointStart = new Point((int) getTranslationX() + ((getWidth() - KeyLayoutSize) / 2), (int) getTranslationY());
rightBoundary = (int) (getWidth() + getTranslationX());
} else {
pointStart = new Point((int) getTranslationX(), (int) getTranslationY() + (getHeight() - KeyLayoutSize) / 2);
rightBoundary = (int) (getTranslationX() + ((getWidth() - KeyLayoutSize) / 2 + KeyLayoutSize));
}
//循环生成对应按钮
for (int i = 0; i < keys.length; i++) {
if (pointStart.x >= rightBoundary) {
//重置计算点坐标
pointStart.x = rightBoundary - KeyLayoutSize;
pointStart.y += keySize;
}
Rect bound = new Rect(pointStart.x, pointStart.y, pointStart.x + keySize, pointStart.y + keySize);
keys[i] = new keys(bound, defaultRadius);
pointStart.x = pointStart.x + keySize;
}
}
处理整个控件的触摸事件.即可处理对应的滑动解锁事件。
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
resetKeyStatus();//重置当前选中状态
touchPoint = new Point((int) event.getX(), (int) event.getY());
case MotionEvent.ACTION_MOVE:
checkInKeys(event.getX(), event.getY()); //效验是否进入进入某个按钮范围
touchPoint.x = (int) event.getX();
touchPoint.y = (int) event.getY();
break;
case MotionEvent.ACTION_UP:
touchPoint = null;//制空当前触摸点位置
if (onConfirmPassListener != null && trail.size() >= minPassSize) {//滑动操作完成回调
onConfirmPassListener.onConfirm(pass);
}
break;
}
invalidate();//重新绘制
return true;
}
重置 和 判断事件代码
// 判断是否选择中
private void checkInKeys(float x, float y) {//x y 为当前触摸的坐标点
for (int index = 0; index < keys.length; index++) {
if (x > keys[index].bound.left + confirmSize && x < keys[index].bound.right - confirmSize) {
if (y > keys[index].bound.top + confirmSize && y < keys[index].bound.bottom - confirmSize) {
if (keys[index].isSelect)
continue;
keys[index].isSelect = true;
if (keyValues != null)
pass += keyValues[index];
trail.add(new Point(keys[index].bound.centerX(), keys[index].bound.centerY()));
}
}
}
}
/**
* 重置按钮状态
*/
private void resetKeyStatus() {
pass = "";
selectedColor = defaultSelectColor;
trail.clear();
for (KeyBroadView.keys key : keys) {
key.isSelect = false;
}
}
```
1. 回调事件添加
> 此处设定实在Activity中进行对应的效验操作,所以对外暴露一个对应的接口,进行回调并返回对
应的获取参数
```java
public interface ConfirmPassListener {
//返回密码
void onConfirm(String pass);
}
以上,便是实现整个流程的基本步骤了。如果需要源码。可到GitHub下载。
如果觉得有任何问题,欢迎提出,并改进。