最近写了个九宫格手势解锁,先附上效果图吧?
上面是效果图,再附上代码?行。
Github 戳我
这篇博客讲述一下实现这个效果的思路。我觉得知道了这个思路,并且顺着这个思路走,每个人都可以自己写一个出来。但是写出来的代码健壮否,就看个人功底了。
在这个代码里你只需要做两件事
记下来我们肢解一下知识点。
在onDraw方法中,需要做四件事:
viewImpl.initData(viewWidth, viewHeight); //初始化9个点数据
viewImpl.onDrawInitView(paint, canvas); //初始化View
viewImpl.onDrawSelectView(paint, canvas); //绘制选中的View
viewImpl.onDrawLineView(paint, canvas); //绘制连接线
我们需要重写onTouchEvent,在onTouchEvent方法中我们可以处理三个事件:
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN : {
viewImpl.touchDown(event);
break;
}
case MotionEvent.ACTION_MOVE : {
viewImpl.touchMove(event);
break;
}
case MotionEvent.ACTION_UP : {
viewImpl.touchUp(event);
break;
}
}
return true;
}
这三个事件中,一个一个说
总结用到的数学知识点:
至此我们的整体流程讲完了。接下来说一下我们的这个Demo的功能点:
属性设置
上述列出了该Demo支持的属性。
支持自定义大圆,小圆,以及连接的线段
方法 | 参数 |
---|---|
setHandleBigGraphical | IGraphicalView接口 |
setHandleSmallGraphical | IGraphicalView接口 |
setHandleLineGraphical | IGraphicalView接口 |
/**
* FileName:IGraphicalView
* Create By:liumengqiang
* Description:自定义需要实现的接口
*/
public interface IGraphicalView {
/**
* 初始化绘制
* @param paint 画笔
* @param canvas 画板
* @param coordinateList 9个点的中心点坐标
* @param attrsModel 属性对象
*/
void onDrawInitView(Paint paint, Canvas canvas, List coordinateList, AttrsModel attrsModel);
/**
*
* @param paint
* @param canvas
* @param selectMap 当前选中点的信息
* @param attrsModel
* @param TYPE 当前的类型(成功?错误?绘制中?)
*/
void onDrawSelectView(Paint paint, Canvas canvas, LinkedHashMap selectMap, AttrsModel attrsModel, int TYPE);
}
详细的自定义可见:HandleBigGraphical类。
支持自定义手势结果处理器
支持自定义手势结果处理器
支持自定义手势结果处理器
这个功能点肯定很重要吧,因为,你想自己处理手势的判断逻辑。我们可能是设置密码,也可能是验证密码,这样的处理逻辑是不一样的,这时候我们就可以自定义。
方法 | 参数 | 返回值 |
---|---|---|
setProcessor | IProcessor接口 | TYPE_COMPLETE,TYPE_ERROR, TYPE_RESET |
示例详见:CheckGestureProcessor类,设置手势示例。
public class CheckGestureProcessor implements IProcessor{
private String gestureValue;
public CheckGestureHandleData() {
}
/**
*
* @param selectIndexArray
* @return
*/
public int handleData(Set selectIndexArray) {
if(gestureValue.equals(getGestureValue(selectIndexArray))) { //密码一致
return GestureViewType.TYPE_COMPLETE;
} else { // 密码不一致
return GestureViewType.TYPE_ERROR;
}
}
private String getGestureValue(Set selectIndexArray) {
String value = "";
for(Integer integer : selectIndexArray) {
value += integer;
}
return value;
}
@Override
public void setGestureValue(String gestureValue) {
if(gestureValue == null) {
throw new IllegalArgumentException("输入参数GestureValue非法!");
} else {
this.gestureValue = gestureValue;
}
}
}
handleData方法内部处理自定需要自定义的逻辑。
然后设置自定义处理:
gestureView.setiHandleData(new CheckGestureProcessor());
结果回调GestureListener
方法 | 描述 |
---|---|
onStart | 手势开始时触发 |
onPointNumberChange | 移动过程中,选中点时触发 |
onComplete | 设置成功时触发 |
onFailed | 小于最低设置的点个数触发 |
valueDisaccord | 输入手势值不一样时触发 |
transitionStatus | 过渡状态触发(需要多次输入校验,比如:设置密码) |
如下示例:
gestureView.setGestureListener(new GestureListener() {
@Override
public void valueDisaccord() {
Toast.makeText(CheckGestureActivity.this, "输入密码错误", Toast.LENGTH_SHORT).show();
}
@Override
public void transitionStatus() {
}
@Override
public void onStart() {
Log.e(TAG , "初始化完成");
}
@Override
public void onPointNumberChange(int selectIndex) {
Log.e(TAG, "点被选中");
}
@Override
public void onComplete(List list) {
Toast.makeText(CheckGestureActivity.this, "校验成功", Toast.LENGTH_SHORT).show();
}
@Override
public void onFailed() {
Toast.makeText(CheckGestureActivity.this, "个数小于四个", Toast.LENGTH_SHORT).show();
}
});
基本功能点讲完了,如果听的有点迷糊,我觉得下载一下Demo,然后对照 Demo跑一遍,就OK了。
再附上一张整体效果Gif:
这个Demo还是缺点还是有的:
这些后续再补上。
好了欢迎大家Star。如果BUG欢迎指正。
Github 戳我
Github 戳我
Github 戳我
Github 戳我