一、今日目的
1.實現(xiàn)密碼保存
2.完結(jié)圖案解鎖
二、知識點
1. 記錄密碼
思路:用字符串表示密碼——將tag值拼入該字符串。既然要拼接所以不能用String,就定義一個StringBuilder(或者StringBuffer)變量。
代碼:
//保存密碼
StringBuilder password;
//密碼
String firpassword;//第一次設(shè)置的
String orgpassword;;//原始密碼
如果某個點被點亮了,就加入密碼
password.append(selected.getTag());
沒有原始密碼,設(shè)置:
第一次密碼的設(shè)置
firpassword = password.toString();
第二次
if(firpassword.equals(password.toString())){
alterTextView.setText("密碼設(shè)置成功");
SharedPreferences ap = getSharedPreferences("tyn",MODE_PRIVATE);
SharedPreferences.Editor editor = ap.edit();
editor.putString("password",firpassword);
editor.commit();
}else {
alterTextView.setText("兩次密碼設(shè)置不一致,請重新輸入");
firpassword = null;
}
有原始密碼,輸入:
if(password.toString().equals(orgpassword) ){
alterTextView.setText("密碼正確");
for (ImageView dd:selectedList){
dd.setVisibility(View.INVISIBLE);
RelativeLayout relativeLayout = findViewById(R.id.root_layout);
relativeLayout.findViewWithTag(((Integer)dd.getTag()+100)).setVisibility(View.VISIBLE);
}
}else {
alterTextView.setText("密碼錯誤請重新輸入");
for(ImageView dd :selectedList){
dd.setVisibility(View.INVISIBLE);
RelativeLayout relativeLayout = findViewById(R.id.root_layout);
ImageView imageView =relativeLayout.findViewWithTag((Integer)dd.getTag()+100);
wSelectedList.add(imageView);
}
for(ImageView ww : wSelectedList){
ww.setVisibility(View.VISIBLE);
}
}
2. 手指離開界面實現(xiàn)密碼清空和界面清空
界面清空的思路:做成一個函數(shù),在需要的地方調(diào)用
代碼:
public void clean(){
password.setLength(0);
for(ImageView i:selectedList){
i.setVisibility(View.INVISIBLE);
}
for(ImageView i:wSelectedList){
i.setVisibility(View.INVISIBLE);
}
selectedList.clear();
wSelectedList.clear();
}
3. 創(chuàng)建文本視圖(昨天在.xml里的TextView終于有用了)
直接上代碼:
//顯示的文本信息
TextView alterTextView;
相應(yīng)的地方,對應(yīng)一下文本輸入
alterTextView.setText("請確認密碼");
alterTextView.setText("密碼設(shè)置成功");
alterTextView.setText("兩次密碼設(shè)置不一致,請重新輸入");
alterTextView.setText("密碼正確");
alterTextView.setText("密碼錯誤請重新輸入");
4. Android里的4種數(shù)據(jù)存儲
- sharedPreferance偏好設(shè)置
- file 小
- salite 大
- network
ps:前三種都是儲存再本地
三、實際應(yīng)用(完整代碼)
package com.example.day3jieshuo;
import androidx.appcompat.app.AppCompatActivity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
//定義一個數(shù)組 保存每個點的控件
ArrayList<ImageView> dotsList;
ArrayList<ImageView> rdotsList;
ArrayList<Integer> lineViewTags;
int tag;
int wtag;
//保存上一次被點亮的點的對象
ImageView lastSelectedDot;
//保存密碼
StringBuilder password;
//顯示的文本信息
TextView alterTextView;
//已經(jīng)點亮的控件
ArrayList<ImageView> selectedList;
ArrayList<ImageView> wSelectedList;
//密碼
String firpassword;
String orgpassword;
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
//判斷是否已經(jīng)顯示
if (hasFocus){
//獲取容器?
RelativeLayout rl = findViewById(R.id.root_layout);
//獲取背景視圖
ImageView iv = findViewById(R.id.opView);
//獲取x 和 y坐標
int x = iv.getLeft();
int y = iv.getTop();
//獲取屏幕密度
float scale = getResources().getDisplayMetrics().density;
tag = 12;
wtag = 112;
//創(chuàng)建橫線 6條
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 2; j++) {
//創(chuàng)建一個視圖用于顯示線
ImageView lineView = new ImageView(this);
lineView.setBackgroundResource(R.drawable.normal_highlight1);
lineView.setVisibility(View.INVISIBLE);
//設(shè)置tag值
lineView.setTag(tag);
//將tag值存入數(shù)組
lineViewTags.add(tag);
tag += 11;
//創(chuàng)建布局參數(shù)
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); params.leftMargin = (int)(x + 46.6*scale) + (int)(99*scale*j); params.topMargin = (int)(y + 170*scale) + (int)(99*scale*i); rl.addView(lineView, params);
params.leftMargin = (int)(x + 50*scale) + (int)(99*scale*j);
params.topMargin = (int)(y + 170*scale) + (int)(99*scale*i);
//創(chuàng)建一個視圖用于顯示線
ImageView wLineView = new ImageView(this);
wLineView.setVisibility(View.INVISIBLE);
wLineView.setBackgroundResource(R.drawable.wrong_highlight1);
//設(shè)置tag值
wLineView.setTag(wtag);
//將tag值存入數(shù)組
lineViewTags.add(wtag);
wtag += 11;
rl.addView(wLineView,params);
}
tag += 11;
wtag += 11;
}
tag = 14;
//創(chuàng)建豎線 4條
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
//創(chuàng)建一個視圖用于顯示線
ImageView lineView = new ImageView(this);
lineView.setBackgroundResource(R.drawable.normal_highlight2);
lineView.setVisibility(View.INVISIBLE);
//設(shè)置tag值
lineView.setTag(tag);
//將tag值存入數(shù)組
lineViewTags.add(tag);
tag += 11;
//創(chuàng)建布局參數(shù)
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT); params.leftMargin = (int)(x + 42*scale) + (int)(99*scale*j); params.topMargin = (int)(y + 170*scale) + (int)(99*scale*i); rl.addView(lineView, params);
}
}
tag = 24;
int rtag = 15;
wtag = 124;
int wrtag = 115;
//創(chuàng)建斜線
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
//創(chuàng)建?一個視圖用于顯示線
ImageView rLineView = new ImageView(this);
//設(shè)置圖片
rLineView .setBackgroundResource(R.drawable.normal_highlight3);
//設(shè)置tag值
rLineView.setTag(rtag);
//將tag值存入數(shù)組
lineViewTags.add(rtag);
rtag += 11;
//創(chuàng)建布局參數(shù)
rLineView.setVisibility(View.INVISIBLE);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); params.leftMargin = (int)(x + 42*scale) + (int)(99*scale*j); params.topMargin = (int)(y + 170*scale) + (int)(99*scale*i); rl.addView(rLineView, params);
//
ImageView lLineView = new ImageView(this);
lLineView.setVisibility(View.INVISIBLE);
lLineView.setBackgroundResource(R.drawable.normal_highlight4);
lLineView.setTag(tag);
lineViewTags.add(tag);
tag += 11;
params.leftMargin = (int)(x + 50*scale) + (int)(99*scale*j);
params.topMargin = (int)(y + 170*scale) + (int)(99*scale*i);
rl.addView(lLineView,params);
//wrong
//創(chuàng)建?一個視圖用于顯示線
ImageView wrLineView = new ImageView(this);
//設(shè)置圖片
wrLineView .setBackgroundResource(R.drawable.wrong_highlight3);
//設(shè)置tag值
wrLineView.setTag(wrtag);
//將tag值存入數(shù)組
lineViewTags.add(wrtag);
wrtag += 11;
//創(chuàng)建布局參數(shù)
params.leftMargin = (int)(x + 50*scale) + (int)(99*scale*j);
params.topMargin = (int)(y + 174*scale) + (int)(99*scale*i);
wrLineView.setVisibility(View.INVISIBLE);
//
ImageView wlLineView = new ImageView(this);
wlLineView.setVisibility(View.INVISIBLE);
wlLineView.setBackgroundResource(R.drawable.wrong_highlight4);
wlLineView.setTag(wtag);
lineViewTags.add(wtag);
wtag += 11;
rl.addView(wrLineView,params);
rl.addView(wlLineView,params);
}
rtag += 11;
tag += 11;
wtag += 11;
wrtag += 11;
}
tag = 1;
//創(chuàng)建9個綠點
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
//創(chuàng)建?用于顯示點的視圖
ImageView dotView = new ImageView(this);;
dotView.setTag(tag);
tag += 1;
//隱藏視圖
dotView.setVisibility(View.INVISIBLE);
//顯示對應(yīng)的圖片
dotView.setBackgroundResource(R.drawable.selected_dot);
//創(chuàng)建控件的尺寸
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); params.leftMargin = (int)(x + 35.33*scale) + (int)(98.66*scale*i); params.topMargin = (int)(y + 162*scale) + (int)(98.66*scale*j);
params.leftMargin = (int)(x + 35.33*scale) + (int)(99*scale*j);
params.topMargin = (int)(y + 162*scale) + (int)(99*scale*i);
//將控件添加到容器中
rl.addView(dotView, params);
//將這個控件添加到數(shù)組
dotsList.add(dotView);
}
}
tag = 101;
//創(chuàng)建9個紅點
for (int j = 0; j < 3; j++) {
for (int i = 0; i < 3; i++) {
//創(chuàng)建?用于顯示點的視圖
ImageView rdotView = new ImageView(this);;
rdotView.setTag(tag);
tag += 1;
//隱藏視圖
rdotView.setVisibility(View.INVISIBLE);
//顯示對應(yīng)的圖片
rdotView.setBackgroundResource(R.drawable.wrong_dot);
//創(chuàng)建控件的尺寸
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); params.leftMargin = (int)(x + 35.33*scale) + (int)(98.66*scale*i); params.topMargin = (int)(y + 162*scale) + (int)(98.66*scale*j);
//將控件添加到容器中
rl.addView(rdotView, params);
//將這個控件添加到數(shù)組
rdotsList.add(rdotView);
}
}
}
}
//監(jiān)聽觸摸事件
@Override
public boolean onTouchEvent(MotionEvent event) {
//獲取事件的類型
int action = event.getAction();
ImageView selected;
float x;
float y;
//判斷是什么事件
switch (action){
case MotionEvent.ACTION_DOWN:
//點擊
//獲取觸摸點的坐標
x = event.getX();
y = event.getY();
//判斷x y是不是在某個點的范圍內(nèi)
selected = dotOfTouch(x, y);
if (selected != null) {
//點亮
selected.setVisibility(View.VISIBLE);
//記錄當前這個點
lastSelectedDot = selected;
password.append(selected.getTag());
selectedList.add(selected);
}
break;
case MotionEvent.ACTION_MOVE:
//滑動
//獲取觸摸點的坐標
x = event.getX();
y = event.getY();
//判斷x y是不是在某個點的范圍內(nèi)
selected = dotOfTouch(x, y);
if (selected != null) {
//判斷這個點是不是起始點
if(lastSelectedDot == null){
//是起始點
selected.setVisibility(View.VISIBLE);
//記錄
lastSelectedDot = selected;
}else{
//不是起始點
//獲取上一個點和當前點的tag
int lTag = (Integer)lastSelectedDot.getTag();//因為getTag得出的是Object類型的,需要轉(zhuǎn)換
int cTag = (Integer)selected.getTag();
//組成線的tag
int lineTag = lTag > cTag ? cTag*10+lTag : lTag*10+cTag;
// System.out.println(lTag+"_____"+cTag+"_____"+lineTag);
//判斷這條線是否存在
if(lineViewTags.contains(lineTag)){
//線存在 點亮點
selected.setVisibility(View.VISIBLE);
password.append(selected.getTag());
selectedList.add(selected);
//點亮這條線
//獲取容器對象
RelativeLayout rl = findViewById(R.id.root_layout);
//通過tag值找容器里對應(yīng)的子控件
ImageView iv = rl.findViewWithTag(lineTag);
iv.setVisibility(View.VISIBLE);
selectedList.add(iv);
//記錄這個點
lastSelectedDot = selected;
}
}
}
break;
case MotionEvent.ACTION_UP:
//System.out.println(password);
//離開
if(orgpassword == null){
//沒有密碼。設(shè)置
if(firpassword == null){
//第一次
firpassword = password.toString();
alterTextView.setText("請確認密碼");
}else {
//第二次
if(firpassword.equals(password.toString())){
alterTextView.setText("密碼設(shè)置成功");
SharedPreferences ap = getSharedPreferences("tyn",MODE_PRIVATE);
SharedPreferences.Editor editor = ap.edit();
editor.putString("password",firpassword);
editor.commit();
}else {
alterTextView.setText("兩次密碼設(shè)置不一致,請重新輸入");
firpassword = null;
}
}
}else {
//輸入密碼
if(password.toString().equals(orgpassword) ){
alterTextView.setText("密碼正確");
for (ImageView dd:selectedList){
dd.setVisibility(View.INVISIBLE);
RelativeLayout relativeLayout = findViewById(R.id.root_layout);
relativeLayout.findViewWithTag(((Integer)dd.getTag()+100)).setVisibility(View.VISIBLE);
}
}else {
alterTextView.setText("密碼錯誤請重新輸入");
for(ImageView dd :selectedList){
dd.setVisibility(View.INVISIBLE);
RelativeLayout relativeLayout = findViewById(R.id.root_layout);
ImageView imageView =relativeLayout.findViewWithTag((Integer)dd.getTag()+100);
wSelectedList.add(imageView);
}
for(ImageView ww : wSelectedList){
ww.setVisibility(View.VISIBLE);
}
}
}
//清空
clean();
break;
default:
break;
}
return true;
}
//寫?個方法 處理 判斷觸摸點是否在控件內(nèi)部
public ImageView dotOfTouch(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();
//判斷這個點是否在這個范圍內(nèi)
if ((x <= r && x >= dx) && (y <= b && y >= dy)){
return dot;
}
}
return null;
}
//寫一個方法 清空
public void clean(){
password.setLength(0);
for(ImageView i:selectedList){
i.setVisibility(View.INVISIBLE);
}
// for(ImageView i:wSelectedList){
// i.setVisibility(View.INVISIBLE);
// }
selectedList.clear();
wSelectedList.clear();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//實例化
dotsList = new ArrayList<>();
lineViewTags = new ArrayList<>();
password = new StringBuilder();
alterTextView = findViewById(R.id.tv_alert);
selectedList = new ArrayList<>();
wSelectedList = new ArrayList<>();
rdotsList =new ArrayList<>();
//查找偏好設(shè)置里面是否有tyn
SharedPreferences sp = getSharedPreferences("tyn",MODE_PRIVATE);
//獲取tyn對應(yīng)的密碼
orgpassword = sp.getString("password",null);
if(orgpassword == null){
alterTextView.setText("請設(shè)置密碼");
}else {
alterTextView.setText("請輸入密碼");
}
// //讀
// SharedPreferences sp = getSharedPreferences("abc",0);
// //寫
// SharedPreferences.Editor editor = sp.edit();
// editor.putString("tyn","123");
// editor.commit();
//
// String result = sp.getString("tyn",null);
// System.out.println(result);
}
}
四、心得
雞湯時間:
常識和 經(jīng)驗有時候能幫助我們少走彎路,有時候卻禁錮了我們的思想,讓我們只能墨守成規(guī),循規(guī)蹈矩。
心里話showtime:
在學了數(shù)組遍歷之后,在思考做那個界面清除的時候就會相到用數(shù)組然后遍歷數(shù)組判斷點亮的控件再去把它們一個個的隱藏起來,這個方法是可以的但是比較麻煩,所以有時候有了經(jīng)驗也要去思考有沒有更好的方法來實現(xiàn)需求。