学习目的
通过学习Android里面的onTouchEvent方法对上篇的图案解锁进行完善,调用touch方法实现触控功能和tag值得用法。
先关技术、及其使用
1、重写onTouchEvent方法
返回值表示表示这个事件是否已经被处理,true表示已经被处理了/消费了,false表示还没有被处理/消费。
在方法里面系统自动将事件包装MotionEvent类,事件有ACTION_DOWN ACTION_MOVE ACTION_UP ACTION_CANSLE,然后通过getAction获取事件
2、在xml里面创建控件并添加id ,在通过Java代码中findViewById 找到对应的控件,用getACtoin获取事件类型
//获取事件类型
int action = event.getAction();
在判断是什么事件,然后实现每个事件的相应功能,touch事件需要获取到触摸点在屏幕上的坐标。
(1)ACTION_DOWN 触摸
case MotionEvent.ACTION_DOWN:
//按下
//获取触摸点的坐标
x = event.getX();
y = event.getY();
//判断 x 和 y 是不是在某个点的范围内
selected = dtoOfTouch(x,y);
if(selected != null) {
//点亮
selected.setVisibility(View.VISIBLE);
//记录当前这个的点
lastSelectDot = selected;
//将tag值拼接到密码中
password.append(selected.getTag());
//将点亮的点添加到这个数组中
selectedList.add(selected);
}
break;
(2)ACTION_MOVE 移动,实现移动功能需要获取到移动过程中划过的点和和线,然后对齐点亮,所以要给对应的点和线添加tag值
case MotionEvent.ACTION_MOVE:
//移动
x = event.getX();
y = event.getY();
//判断 x 和 y 是不是在某个点的范围内
selected = dtoOfTouch(x,y);
if(selected != null) {
//判断这个点是不是第一个点
if(lastSelectDot == null){
//第一个点
selected.setVisibility(View.VISIBLE);
//记录
lastSelectDot = selected;
//将tag值拼接到密码中
password.append(selected.getTag());
//将点亮的点添加到这个数组中
selectedList.add(selected);
}else{
//不是第一个点
//获取上一个点和当前点的tag组成的线的tag值
int LTag = (Integer) lastSelectDot.getTag();
int CTag = (Integer) selected.getTag();
//获取两个线的tag值 small * 10 + big
int LineTag = LTag > CTag ? CTag * 10 +LTag : LTag * 10 + CTag;
//判断这条线是否存在
if(LineTagsList.contains(LineTag)){
//线存在
//点亮点 点亮线
selected.setVisibility(View.VISIBLE);
//将tag值拼接到密码中
password.append(selected.getTag());
//点亮这条线
//获取容器对象
RelativeLayout rl = findViewById(R.id.root_layout);
//通过tag查找子控件
ImageView iv = rl.findViewWithTag(LineTag);
//点亮线
iv.setVisibility(View.VISIBLE);
//将点亮的点添加到这个数组中
selectedList.add(selected);
//将点亮的线添加到这个数组中
selectedList.add(iv);
}
}
}
break;
(3)ACTION_UP离开,离开里面需要将move里面获取绘制的图案保存,保存也是通过记录划过点的tag值进行拼接保存。
case MotionEvent.ACTION_UP:
//离开
// 1、绘制密码 和原始密码比较
// 2、设置密码 第一次
// 3、设置密码 第二次
if(orgPassword != null){
//有密码了 判断是否和原始密码相同
if(password.toString().equals(orgPassword)){
alertTextView.setText("解锁成功");
}else {
alertTextView.setText("解锁密码失败");
}
}else {
//设置密码
//判断是第一次还是第二次确认密码
if(firstPassword == null){
//设置密码的第一次
firstPassword = password.toString();
//提示确认密码
alertTextView.setText("请确认密码图案");
}else {
//第二次确认密码
//判断两次是否一致
if(firstPassword.equals(password.toString())){
//设置成功
alertTextView.setText("设置密码成功");
//保存密码
SharedPreferences sp = getSharedPreferences("passwrod",MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString("pwd",firstPassword);
editor.commit();
}else {
//设置失败
alertTextView.setText("两次密码不一致,请重新设置");
firstPassword = null;
}
}
}
clean();
另外,还需要写clean方法对所选的图案进行清空,以及dtoOfTouch方法来判断触摸点是否在控件内部
clean方法
//清空
public void clean(){
password.setLength(0);
//隐藏所有选中发的视图 点 线
for(ImageView iv : selectedList){
iv.setVisibility(View.INVISIBLE);
}
//清空数组
selectedList.clear();
}
dtoOfTouch 方法
//写一个方法用于处理判断触摸点是否在某个控件内部
public ImageView dtoOfTouch(float x ,float y){
//遍历数组
for (ImageView dot : dotsList){
//获取这个dot相对于屏幕的x和y
int[] loc = new int[2];
dot.getLocationOnScreen(loc);
int dx = loc[0];
int dy = loc[1];
//获取右边的偏移量
int r = dx + dot.getWidth();
//获取最底部的偏移量
int b = dy + dot.getHeight();
//判断这个控件是否在这个范围内
if(( x <= r && x>= dx ) && (y <= b && y >=dy)){
return dot;
}
}
return null;
}
PS
学习了tag值得相关使用,但是还是不太懂tag值得用法,只清楚tag在代码中起什么作用,清楚了如何让控件切换到屏幕的坐标系。