Android_开发_Day23_图案解锁(下)

Android_开发Day23图案解锁

目的:

综合运用Java以及C语言的思想来解决问题

技术:

<1> onTouchEvent:

onTouchEvent方法是当屏幕被触摸时系统调用的方法,MotionEvent是获取触摸信息,可以通过该类的getAction()方法来得到触摸事件的类型,该方法的返回值是一个整型,因此可以通过判断数值来判断是什么手势,常用的手势有:
MotionEvent.ACTION_DOWN(点按屏幕)
MotionEvent.ACTION_MOVE(屏幕滑动)
MotionEvent.ACTION_UP(手指抬起)

<2> SharedPreferences:

SharedPreferences是一个与文件操作相关的类主要是储存一些小数据还是基本数据,如文本。SharedPreferences在创建对象时不能用构造方法要用getSharedPreferences("文件名", 读写方式)函数来创建,其中的即可读也可写的方式用数值0表示,一般就用该方式,值得注意的是任何一个SharedPreferences对象只能读数据不能写,因为写需要用该类的一个内部类来实现SharedPreferences.Editor类,调用SharedPreferences里面的edit()方法就能够得到一个SharedPreferences.Editor对象,然后用调用方法putString("键", 值)来写入字符串,当然不止这个方法还有putInt(),putFloat()等方法但是只能放一些基本数据类型。但是这里我们只需要放字符串就够了所以用SharedPreferences。

技术如何使用:

接着上次的图案解锁,创建好界面后就将点与线隐藏,当用户划过点时点亮点,划过两个点时判断两点之间有没有线连接,如果有就点亮点和之间的线,如何判断用户是否划过点呢,由于每个点是一个图片,因此只要获取点按的坐标看是否在图片所在的区域就行了。代码如下:

@Override
    public boolean  onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        switch (action){
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_MOVE:
                //移动
                //获取x,y
                if (!isUnclock) {
                    x = event.getX();
                    y = event.getY();

                    //判断
                    select = dotOfTouch(x, y);
                    if (select != null) {
                        //判断是不是第一个点
                        if (lastTag == null) {
                            //点亮这个点
                            select.setVisibility(View.VISIBLE);
                            //记录这个点
                            lastTag = select;
                        } else {
                            //不是第一个
                            //获取两个点的tag值
                            int lTag = (Integer) lastTag.getTag();
                            int cTag = (Integer) select.getTag();

                            //获取线的tag
                            Integer lineTag = lTag > cTag ? cTag * 10 + lTag : lTag * 10 + cTag;
                            //判断是否在一条直线
                            for (Integer num : onALine) {
                                String newNum = num.toString();
                                String newLinTad = lineTag.toString();
                                if (newLinTad.startsWith(newNum.substring(0, 1)) && newLinTad.endsWith(newNum.substring(2))) {
                                    String nNum1 = newNum.substring(0, 1) + newNum.substring(1, 2);
                                    String nNum2 = newNum.substring(1, 2) + newNum.substring(2);
                                    if (select.getVisibility() != View.VISIBLE) {
                                        RelativeLayout relativeLayout = findViewById(R.id.cl_main);
                                        ImageView imageView = relativeLayout.findViewWithTag(Integer.parseInt(nNum1));
                                        ImageView imageView1 = relativeLayout.findViewWithTag(Integer.parseInt(nNum2));
                                        ImageView dot = relativeLayout.findViewWithTag(Integer.parseInt(newNum.substring(1, 2)));
                                        dot.setVisibility(View.VISIBLE);
                                        imageView.setVisibility(View.VISIBLE);
                                        imageView1.setVisibility(View.VISIBLE);
                                        select.setVisibility(View.VISIBLE);
                                        if (password.length() > 0) {
                                            password.append(nNum1.substring(1, 2));
                                            password.append(select.getTag());
                                        } else {
                                            password.append(lastTag.getTag());
                                            password.append(nNum1.substring(1, 2));
                                            password.append(select.getTag());
                                        }
                                        lastTag = select;
                                    }
                                }
                            }
                            //判断这条线是否存在
                            if (lineList.contains(lineTag)) {
                                //点亮点
                                //点亮线
                                if (select.getVisibility() != View.VISIBLE) {
                                    select.setVisibility(View.VISIBLE);
                                    RelativeLayout rl = findViewById(R.id.cl_main);
                                    ImageView iv = rl.findViewWithTag(lineTag);
                                    iv.setVisibility(View.VISIBLE);
                                    //记录
                                    if (password.length() == 0) {
                                        password.append(lastTag.getTag());
                                        password.append(select.getTag());
                                    } else {
                                        password.append(select.getTag());
                                    }
                                    lastTag = select;
                                }
                            }
                        }
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                //抬起
                //保存密码
                if (!isUnclock) {
                    if (password.length() > 0) {
                        if (hasPassword == false) {
                            //没有密码
                            if (password1 == null) {
                                //第一次
                                text.setText("请确认密码");
                                hide();
                                password1 = password.toString();
                                password.replace(0, password.length(), "");
                            } else {
                                System.out.println(password1 + "___" + password + "____" + password1.length() + "___" + password.length());
                                //有密码了
                                if (password1.equals(password.toString())) {
                                    text.setText("密码设置成功");
                                    //保存密码
                                    SharedPreferences sp = getSharedPreferences("password", 0);
                                    SharedPreferences.Editor editor = sp.edit();
                                    editor.putString("pwd", password.toString());
                                    editor.commit();
                                } else {
                                    text.setText("两次密码绘制不一致,请重新绘制");
                                    hide();
                                    password.replace(0, password.length(), "");
                                    password1 = null;
                                }
                            }
                        } else {
                            if (getPassword1.equals(password.toString())) {
                                text.setText("解锁成功");
                                ImageView iv = findViewById(R.id.iv_p8);
                                hide();
                                iv.setVisibility(View.VISIBLE);
                                isUnclock = true;
                            } else {
                                text.setText("密码错误,请重新绘制");
                                hide();
                                password.replace(0, password.length(), "");
                            }
                        }
                    }
                }
                break;
            default:
                break;
        }
        return true;
    }

    //写一个方法判断触摸点是否在某个控件内部
    public ImageView dotOfTouch(float x,float y){
        //遍历数组
        int[] loc = new int[2];
        for (ImageView dot: dotsList) {
            dot.getLocationOnScreen(loc);
            if ((x <= loc[0] + dot.getWidth() && x >= loc[0]) && (y <= loc[1] + dot.getHeight() && y >= loc[1])){
                return dot;
            }
        }
        return null;
    }
    //将所有的已经显示的控件隐藏
    public void hide(){
        for (ImageView dot:dotsList) {
            dot.setVisibility(View.INVISIBLE);
        }
        RelativeLayout rl = findViewById(R.id.cl_main);
        for (Integer i: lineList) {
            rl.findViewWithTag(i).setVisibility(View.INVISIBLE);
            lastTag = null;
        }
    }

当然我们不能光做出效果还要有点实际的东西,需要记录密码,为每个点设置tag值,一般是按照123456789来的,因此点亮一个点时需要记录该点的tag值并与之前的值连接起来形成一个字符串,就是密码了,因此可以将这个密码存到文件中就行了,下次打开时密码就不用设置了。到这里整个项目就结束了,整体代码可以展示出来:

public class MainActivity extends AppCompatActivity {

    ArrayList dotsList;
    ArrayList lineList;
    int tag;
    ImageView lastTag;
    StringBuilder password = new StringBuilder();
    TextView text;
    String password1 = null;
    boolean hasPassword;
    String getPassword1;
    boolean isUnclock = false;

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        //获取屏幕密度
        float a = getResources().getDisplayMetrics().density;
        //判断是否已经显示
        if (hasFocus) {
            //获取容器
            RelativeLayout rl = findViewById(R.id.cl_main);
            //获取背景视图
            ImageView iv = findViewById(R.id.opView);
            //获取x和y
            int x = iv.getLeft();
            int y = iv.getTop();

            //创建横线
            tag = 1;
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 2; j++) {
                    //创建一个视图显示线
                    ImageView lineView = new ImageView(this);
                    //设置图片
                    lineView.setBackgroundResource(R.drawable.normal_highlight1);
                    //设置tag值
                    tag+=11;
                    lineView.setTag(tag);
                    //加tag值
                    lineList.add(tag);
                    //创建布局参数
                    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                    params.leftMargin = (int) (x + 46.6 * a + 99 * a * j);
                    params.topMargin = (int) (y + 170 * a + 99 * a * i);
                    rl.addView(lineView, params);
                    //lineView.setVisibility(View.INVISIBLE);

                }
                tag+=11;
            }
            //创建竖线
            tag = 14;
            for (int i = 0; i < 2; i++) {
                for (int j = 0; j < 3; j++) {
                    //创建一个视图显示线
                    ImageView lineView = new ImageView(this);
                    //设置图片
                    lineView.setBackgroundResource(R.drawable.normal_highlight2);
                    //添加tag值
                    lineView.setTag(tag);
                    //加tag值
                    lineList.add(tag);
                    tag+=11;
                    //创建布局参数
                    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                    params.leftMargin = (int) (x + 42 * a + 99 * a * j);
                    params.topMargin = (int) (y + 170 * a + 99 * a * i);
                    rl.addView(lineView, params);
                    //lineView.setVisibility(View.INVISIBLE);

                }
            }
            //创建右竖线
            tag = 15;
            for (int i = 0; i < 2; i++) {
                for (int j = 0; j < 2; j++) {
                    //创建一个视图显示线
                    ImageView lineView = new ImageView(this);
                    //设置图片
                    lineView.setBackgroundResource(R.drawable.normal_highlight3);
                    //添加tag值
                    lineView.setTag(tag);
                    //加tag值
                    lineList.add(tag);
                    tag+=11;

                    //创建布局参数
                    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                    params.leftMargin = (int) (x + 42 * a + 99 * a * j);
                    params.topMargin = (int) (y + 170 * a + 99 * a * i);
                    rl.addView(lineView, params);
                    //lineView.setVisibility(View.INVISIBLE);

                }
                tag+=11;
            }
            //创建左竖线
            tag = 24;
            for (int i = 0; i < 2; i++) {
                for (int j = 0; j < 2; j++) {
                    //创建一个视图显示线
                    ImageView lineView = new ImageView(this);
                    //设置图片
                    lineView.setBackgroundResource(R.drawable.normal_highlight4);
                    //设置tag值
                    lineView.setTag(tag);
                    //加tag值
                    lineList.add(tag);
                    tag+=11;
                    //创建布局参数
                    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                    params.leftMargin = (int) (x + 54 * a + 99 * a * j);
                    params.topMargin = (int) (y + 170 * a + 99 * a * i);
                    rl.addView(lineView, params);
                    //lineView.setVisibility(View.INVISIBLE);

                }
                tag+=11;
            }
            //九个点
            tag = 1;
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 3; j++) {
                    //创建用于显示点的视图
                    ImageView dotView = new ImageView(this);
                    //设置对应的tag值
                    dotView.setTag(tag++);
                    //隐藏视图
                    dotView.setVisibility(View.VISIBLE);
                    //显示对应的图片
                    dotView.setBackgroundResource(R.drawable.selected_dot);
                    //创建控件的尺寸
                    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

                    params.leftMargin = (int) (x + 35 * a + 99 * a * j);
                    params.topMargin = (int) (y + 164 * a + 99 * a * i);

                    //将子控件添加到容器中
                    rl.addView(dotView, params);
                    //dotView.setVisibility(View.INVISIBLE);

                    //将控件放到数组里面
                    dotsList.add(dotView);
                }
            }
        }
    }

    int[] onALine = {123,456,789,147,159,258,369,357};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        System.out.println("here");

        dotsList = new ArrayList<>();
        lineList = new ArrayList<>();

      text = findViewById(R.id.tv_text);
      //显示请设置密码
       SharedPreferences sp = getSharedPreferences("password",0);
       if (sp.getString("pwd",null) == null) {
           text.setText("请设置密码");
           hasPassword = false;
       }else {
           text.setText("请绘制您的图案");
           getPassword1 = sp.getString("pwd",null);
           hasPassword = true;
    }

        ImageView iv = findViewById(R.id.iv_p8);
        iv.setVisibility(View.INVISIBLE);
    }
    float x;
    float y;
    ImageView select;
    Integer a = 1;
    int i = 0;

    //监听事件

    @Override
    public boolean  onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        switch (action){
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_MOVE:
                //移动
                //获取x,y
                if (!isUnclock) {
                    x = event.getX();
                    y = event.getY();

                    //判断
                    select = dotOfTouch(x, y);
                    if (select != null) {
                        //判断是不是第一个点
                        if (lastTag == null) {
                            //点亮这个点
                            select.setVisibility(View.VISIBLE);
                            //记录这个点
                            lastTag = select;
                        } else {
                            //不是第一个
                            //获取两个点的tag值
                            int lTag = (Integer) lastTag.getTag();
                            int cTag = (Integer) select.getTag();

                            //获取线的tag
                            Integer lineTag = lTag > cTag ? cTag * 10 + lTag : lTag * 10 + cTag;
                            //判断是否在一条直线
                            for (Integer num : onALine) {
                                String newNum = num.toString();
                                String newLinTad = lineTag.toString();
                                if (newLinTad.startsWith(newNum.substring(0, 1)) && newLinTad.endsWith(newNum.substring(2))) {
                                    String nNum1 = newNum.substring(0, 1) + newNum.substring(1, 2);
                                    String nNum2 = newNum.substring(1, 2) + newNum.substring(2);
                                    if (select.getVisibility() != View.VISIBLE) {
                                        RelativeLayout relativeLayout = findViewById(R.id.cl_main);
                                        ImageView imageView = relativeLayout.findViewWithTag(Integer.parseInt(nNum1));
                                        ImageView imageView1 = relativeLayout.findViewWithTag(Integer.parseInt(nNum2));
                                        ImageView dot = relativeLayout.findViewWithTag(Integer.parseInt(newNum.substring(1, 2)));
                                        dot.setVisibility(View.VISIBLE);
                                        imageView.setVisibility(View.VISIBLE);
                                        imageView1.setVisibility(View.VISIBLE);
                                        select.setVisibility(View.VISIBLE);
                                        if (password.length() > 0) {
                                            password.append(nNum1.substring(1, 2));
                                            password.append(select.getTag());
                                        } else {
                                            password.append(lastTag.getTag());
                                            password.append(nNum1.substring(1, 2));
                                            password.append(select.getTag());
                                        }
                                        lastTag = select;
                                    }
                                }
                            }
                            //判断这条线是否存在
                            if (lineList.contains(lineTag)) {
                                //点亮点
                                //点亮线
                                if (select.getVisibility() != View.VISIBLE) {
                                    select.setVisibility(View.VISIBLE);
                                    RelativeLayout rl = findViewById(R.id.cl_main);
                                    ImageView iv = rl.findViewWithTag(lineTag);
                                    iv.setVisibility(View.VISIBLE);
                                    //记录
                                    if (password.length() == 0) {
                                        password.append(lastTag.getTag());
                                        password.append(select.getTag());
                                    } else {
                                        password.append(select.getTag());
                                    }
                                    lastTag = select;
                                }
                            }
                        }
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                //抬起
                //保存密码
                if (!isUnclock) {
                    if (password.length() > 0) {
                        if (hasPassword == false) {
                            //没有密码
                            if (password1 == null) {
                                //第一次
                                text.setText("请确认密码");
                                hide();
                                password1 = password.toString();
                                password.replace(0, password.length(), "");
                            } else {
                                System.out.println(password1 + "___" + password + "____" + password1.length() + "___" + password.length());
                                //有密码了
                                if (password1.equals(password.toString())) {
                                    text.setText("密码设置成功");
                                    //保存密码
                                    SharedPreferences sp = getSharedPreferences("password", 0);
                                    SharedPreferences.Editor editor = sp.edit();
                                    editor.putString("pwd", password.toString());
                                    editor.commit();
                                } else {
                                    text.setText("两次密码绘制不一致,请重新绘制");
                                    hide();
                                    password.replace(0, password.length(), "");
                                    password1 = null;
                                }
                            }
                        } else {
                            if (getPassword1.equals(password.toString())) {
                                text.setText("解锁成功");
                                ImageView iv = findViewById(R.id.iv_p8);
                                hide();
                                iv.setVisibility(View.VISIBLE);
                                isUnclock = true;
                            } else {
                                text.setText("密码错误,请重新绘制");
                                hide();
                                password.replace(0, password.length(), "");
                            }
                        }
                    }
                }
                break;
            default:
                break;
        }
        return true;
    }

    //写一个方法判断触摸点是否在某个控件内部
    public ImageView dotOfTouch(float x,float y){

        //遍历数组
        int[] loc = new int[2];
        for (ImageView dot: dotsList) {
            dot.getLocationOnScreen(loc);
            if ((x <= loc[0] + dot.getWidth() && x >= loc[0]) && (y <= loc[1] + dot.getHeight() && y >= loc[1])){
                return dot;
            }
        }
        return null;
    }
    //将所有的已经显示的控件隐藏
    public void hide(){
        for (ImageView dot:dotsList) {
            dot.setVisibility(View.INVISIBLE);
        }
        RelativeLayout rl = findViewById(R.id.cl_main);
        for (Integer i: lineList) {
            rl.findViewWithTag(i).setVisibility(View.INVISIBLE);
            lastTag = null;
        }
    }
}

实际使用效果:

Android_开发_Day23_图案解锁(下)_第1张图片
整体效果图.jpg

总结:

一个完整的项目是很对知识的运用,因此不管是以前学的C语言还是现在学的Java都是在学习思想,现在所学的东西只不过是以前的东西披了一身马甲罢了,只不过加入了界面而已,但是具体的代码实现也就是灵魂还是以前的枯燥的代码。

你可能感兴趣的:(Android_开发_Day23_图案解锁(下))