學習目的
通過學習Android里面的onTouchEvent方法對上篇的圖案解鎖進行完善,調(diào)用touch方法實現(xiàn)觸控功能和tag值得用法。
先關(guān)技術(shù)、及其使用
1、重寫onTouchEvent方法
返回值表示表示這個事件是否已經(jīng)被處理,true表示已經(jīng)被處理了/消費了,false表示還沒有被處理/消費。
在方法里面系統(tǒng)自動將事件包裝MotionEvent類,事件有ACTION_DOWN ACTION_MOVE ACTION_UP ACTION_CANSLE,然后通過getAction獲取事件
2、在xml里面創(chuàng)建控件并添加id ,在通過Java代碼中findViewById 找到對應的控件,用getACtoin獲取事件類型
//獲取事件類型
int action = event.getAction();
在判斷是什么事件,然后實現(xiàn)每個事件的相應功能,touch事件需要獲取到觸摸點在屏幕上的坐標。
(1)ACTION_DOWN 觸摸
case MotionEvent.ACTION_DOWN:
//按下
//獲取觸摸點的坐標
x = event.getX();
y = event.getY();
//判斷 x 和 y 是不是在某個點的范圍內(nèi)
selected = dtoOfTouch(x,y);
if(selected != null) {
//點亮
selected.setVisibility(View.VISIBLE);
//記錄當前這個的點
lastSelectDot = selected;
//將tag值拼接到密碼中
password.append(selected.getTag());
//將點亮的點添加到這個數(shù)組中
selectedList.add(selected);
}
break;
(2)ACTION_MOVE 移動,實現(xiàn)移動功能需要獲取到移動過程中劃過的點和和線,然后對齊點亮,所以要給對應的點和線添加tag值
case MotionEvent.ACTION_MOVE:
//移動
x = event.getX();
y = event.getY();
//判斷 x 和 y 是不是在某個點的范圍內(nèi)
selected = dtoOfTouch(x,y);
if(selected != null) {
//判斷這個點是不是第一個點
if(lastSelectDot == null){
//第一個點
selected.setVisibility(View.VISIBLE);
//記錄
lastSelectDot = selected;
//將tag值拼接到密碼中
password.append(selected.getTag());
//將點亮的點添加到這個數(shù)組中
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);
//將點亮的點添加到這個數(shù)組中
selectedList.add(selected);
//將點亮的線添加到這個數(shù)組中
selectedList.add(iv);
}
}
}
break;
(3)ACTION_UP離開,離開里面需要將move里面獲取繪制的圖案保存,保存也是通過記錄劃過點的tag值進行拼接保存。
case MotionEvent.ACTION_UP:
//離開
// 1、繪制密碼 和原始密碼比較
// 2、設(shè)置密碼 第一次
// 3、設(shè)置密碼 第二次
if(orgPassword != null){
//有密碼了 判斷是否和原始密碼相同
if(password.toString().equals(orgPassword)){
alertTextView.setText("解鎖成功");
}else {
alertTextView.setText("解鎖密碼失敗");
}
}else {
//設(shè)置密碼
//判斷是第一次還是第二次確認密碼
if(firstPassword == null){
//設(shè)置密碼的第一次
firstPassword = password.toString();
//提示確認密碼
alertTextView.setText("請確認密碼圖案");
}else {
//第二次確認密碼
//判斷兩次是否一致
if(firstPassword.equals(password.toString())){
//設(shè)置成功
alertTextView.setText("設(shè)置密碼成功");
//保存密碼
SharedPreferences sp = getSharedPreferences("passwrod",MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString("pwd",firstPassword);
editor.commit();
}else {
//設(shè)置失敗
alertTextView.setText("兩次密碼不一致,請重新設(shè)置");
firstPassword = null;
}
}
}
clean();
另外,還需要寫clean方法對所選的圖案進行清空,以及dtoOfTouch方法來判斷觸摸點是否在控件內(nèi)部
clean方法
//清空
public void clean(){
password.setLength(0);
//隱藏所有選中發(fā)的視圖 點 線
for(ImageView iv : selectedList){
iv.setVisibility(View.INVISIBLE);
}
//清空數(shù)組
selectedList.clear();
}
dtoOfTouch 方法
//寫一個方法用于處理判斷觸摸點是否在某個控件內(nèi)部
public ImageView dtoOfTouch(float x ,float y){
//遍歷數(shù)組
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();
//判斷這個控件是否在這個范圍內(nèi)
if(( x <= r && x>= dx ) && (y <= b && y >=dy)){
return dot;
}
}
return null;
}
PS
學習了tag值得相關(guān)使用,但是還是不太懂tag值得用法,只清楚tag在代碼中起什么作用,清楚了如何讓控件切換到屏幕的坐標系。