安卓小项目之EveryDay(5)--记住密码

本来这次应该是做历史模块的,但是因为接口是从网络上获取的,而聚合数据是需要钱才可以用多个免费接口(这点我就很想吐槽,一个账户只能用一个免费接口,而且每天只能用100次,太坑了),于是我就想先到其他网站看看有没有免费的接口。本次就将这个程序完善的更加像一个应用吧,我计划加入登陆注册功能,包含验证码登陆,第三方登陆,但是没有后台,所以数据只能存在本地的sqlite数据库中,不过这次只讲登陆中的记住密码以及验证功能,先上效果图

安卓小项目之EveryDay(5)--记住密码


第一部分:布局实现

布局效果图:


安卓小项目之EveryDay(5)--记住密码


布局代码:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:layout_marginLeft="16dp"
        android:layout_marginStart="16dp"
        android:layout_marginTop="75dp"
        android:text="登陆"
        android:textColor="#00A600"
        android:textSize="30sp"
        android:textStyle="bold" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginEnd="16dp"
        android:layout_marginLeft="30dp"
        android:layout_marginStart="16dp"
        android:layout_marginTop="20dp"
        android:orientation="vertical"
        android:textStyle="bold">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="50dp"
                android:gravity="center_vertical"
                android:text="手机号码:"
                android:textSize="20sp" />

            <EditText
                android:id="@+id/editPhoneNumber"
                android:hint="请输入手机号"
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:inputType="phone" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp"
            android:orientation="vertical">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="50dp"
                android:gravity="center_vertical"
                android:text="密码:"
                android:textSize="20sp" />

            <EditText
                android:id="@+id/editPassword"
                android:hint="请输入密码"
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:inputType="textPassword" />
        </LinearLayout>

        <CheckBox
            android:id="@+id/checkBoxRememberPassword"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="记住密码"
            android:textColor="#4F9D9D" />

        <Button
            android:id="@+id/buttonLogin"
            android:layout_marginTop="5dp"
            android:layout_width="match_parent"
            android:layout_height="51dp"
            android:text="登陆"
            android:textSize="20sp" />

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_marginTop="15dp">

            <TextView
                android:id="@+id/textForgetPassword"
                android:layout_width="wrap_content"
                android:layout_height="25dp"
                android:text="忘记密码"
                android:textColor="#00A600" />

            <TextView
                android:id="@+id/textRegister"
                android:layout_width="wrap_content"
                android:layout_height="25dp"
                android:layout_alignParentRight="true"
                android:text="注册账号"
                android:textColor="#00A600" />
        </RelativeLayout>


    </LinearLayout>

</LinearLayout>

第二部分:账号密码格式正确时登陆按钮可点击


实现思路:1、分别给账号密码加入flag并初始为false


private Boolean isPhoneNumberOk;

private Boolean isPasswordOk;

2、给账号密码加入文本监听器,当然,还需要绑定事件,这里就不一一写了,最后会贴出总代码

//使用文本监听器来检验手机号码输入是否合法
TextWatcher editPhoneNumberWacher = new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void afterTextChanged(Editable editable) {
        String inputStr = editable.toString().trim();
        if (!TextUtils.isEmpty(inputStr) && inputStr.getBytes().length == 11) {
            isPhoneNumberOk = true;
        } else {
            isPhoneNumberOk = false;

        }
        setButtonEnable();
    }
};
//使用文本监听器来检验密码输入是否合法
TextWatcher editPasswordWacher = new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void afterTextChanged(Editable editable) {
        String inputStr = editable.toString().trim();
        if (!TextUtils.isEmpty(inputStr) && inputStr.getBytes().length >= 6) {
            isPasswordOk = true;
        } else {
            isPasswordOk = false;

        }
        setButtonEnable();
    }
};

3、用一个方法来控制登陆按钮是否可以点击



//当两个输入项格式都合法时 button才可以点击
private void setButtonEnable() {
    if (isPasswordOk && isPhoneNumberOk) {
        buttonLogin.setBackgroundColor(Color.parseColor("#00BB00"));
        buttonLogin.setTextColor(Color.parseColor("#FFFFFF"));
        buttonLogin.setEnabled(true);
    } else {
        buttonLogin.setEnabled(false);
        buttonLogin.setBackgroundColor(Color.parseColor("#E0E0E0"));
    }
}
第三部分:记住密码功能

1、我们使用sharepreference来存储账号密码



preferences = getSharedPreferences("userInformation", MODE_PRIVATE);


2、在onPause中进行对账号密码的存储,就是先获取单选框是否被选中,是就将账号密码还有单选框的状态存入,这里存入单选框是为了在程序刚开始打开时决定是否还原账号密码;如果单选框没有选中,则清空账号密码



@Override
protected void onPause() {
    super.onPause();
    SharedPreferences.Editor editor = preferences.edit();
    //登陆之前先判断用户是否勾选了记住密码 是则把单选框的状态和账号密码存入sharepreference中
    if (checkBoxRememberPassword.isChecked()) {
        editor.putBoolean("isNeedSave", true);
        editor.putString("phoneNumber", editPhoneNumber.getText().toString().trim());
        editor.putString("password", editPassword.getText().toString().trim());
        //提交本次填写
        editor.commit();
    } else {//不是则将sharepreference中的单选框状态设置为false,并清空账号密码
        editor.putBoolean("isNeedSave", false);
        editor.remove("phoneNumber");
        editor.remove("password");
        editor.commit();
    }
}


3、在onCreate中还原账号密码,还原的依据来源就是根据我们存入文件的单选框状态,true表示需要还原,并且在还原的时候还需要将登陆按钮设置为可点击,至于为什么,也会在总结中解析


private void initData() {
    //使用sharepreference来保存程序中用户的一些资料
    preferences = getSharedPreferences("userInformation", MODE_PRIVATE);
    //初始时将需要输入的两个参数都设置为false 只要两者都为真时 登陆按钮才会可点击
    isPhoneNumberOk = false;
    isPasswordOk = false;
    //初始时登陆按钮不可点击
    buttonLogin.setEnabled(false);
    //刚打开activity时进行判断 被选中则还原账号密码

    if (preferences.getBoolean("isNeedSave", false)) {
        //获取电话号码并显示 如果文件中没有phoneNumber则使用-1
        editPhoneNumber.setText(preferences.getString("phoneNumber", "123"));
        editPassword.setText(preferences.getString("password", "123"));
        //用户点击过记住密码以后就默认总是勾选上记住密码
        checkBoxRememberPassword.setChecked(true);
        //将账号密码还原后还需要将button设置为可点击状态
        buttonLogin.setEnabled(true);
        buttonLogin.setBackgroundColor(Color.parseColor("#00BB00"));
        buttonLogin.setTextColor(Color.parseColor("#FFFFFF"));
    }
}

总代码:


package com.everyday.wei.everyday;

import android.app.Activity;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

/**
 * Created by ikecin on 2017/11/23.
 */

public class Login extends Activity {
    @BindView(R.id.editPhoneNumber)
    EditText editPhoneNumber;
    @BindView(R.id.editPassword)
    EditText editPassword;
    @BindView(R.id.checkBoxRememberPassword)
    CheckBox checkBoxRememberPassword;
    @BindView(R.id.buttonLogin)
    Button buttonLogin;
    @BindView(R.id.textForgetPassword)
    TextView textForgetPassword;
    @BindView(R.id.textRegister)
    TextView textRegister;
    private Boolean isPhoneNumberOk;
    private Boolean isPasswordOk;
    SharedPreferences preferences;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        ButterKnife.bind(this);
        initData();
        initUI();
        initEvent();
    }

    @Override
    protected void onPause() {
        super.onPause();
        SharedPreferences.Editor editor = preferences.edit();
        //登陆之前先判断用户是否勾选了记住密码 是则把单选框的状态和账号密码存入sharepreference中
        if (checkBoxRememberPassword.isChecked()) {
            editor.putBoolean("isNeedSave", true);
            editor.putString("phoneNumber", editPhoneNumber.getText().toString().trim());
            editor.putString("password", editPassword.getText().toString().trim());
            //提交本次填写
            editor.commit();
        } else {//不是则将sharepreference中的单选框状态设置为false,并清空账号密码
            editor.putBoolean("isNeedSave", false);
            editor.remove("phoneNumber");
            editor.remove("password");
            editor.commit();
        }
    }

    private void initEvent() {
        editPassword.addTextChangedListener(editPasswordWacher);
        editPhoneNumber.addTextChangedListener(editPhoneNumberWacher);
    }

    private void initUI() {
    }

    private void initData() {
        //使用sharepreference来保存程序中用户的一些资料
        preferences = getSharedPreferences("userInformation", MODE_PRIVATE);
        //初始时将需要输入的两个参数都设置为false 只要两者都为真时 登陆按钮才会可点击
        isPhoneNumberOk = false;
        isPasswordOk = false;
        //初始时登陆按钮不可点击
        buttonLogin.setEnabled(false);
        //刚打开activity时进行判断 被选中则还原账号密码

        if (preferences.getBoolean("isNeedSave", false)) {
            //获取电话号码并显示 如果文件中没有phoneNumber则使用-1
            editPhoneNumber.setText(preferences.getString("phoneNumber", "123"));
            editPassword.setText(preferences.getString("password", "123"));
            //用户点击过记住密码以后就默认总是勾选上记住密码
            checkBoxRememberPassword.setChecked(true);
            //将账号密码还原后还需要将button设置为可点击状态
            buttonLogin.setEnabled(true);
            buttonLogin.setBackgroundColor(Color.parseColor("#00BB00"));
            buttonLogin.setTextColor(Color.parseColor("#FFFFFF"));
        }
    }

    @OnClick({R.id.buttonLogin, R.id.textForgetPassword, R.id.textRegister})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.buttonLogin:
                compareLoginInformation();
                break;
            case R.id.textForgetPassword:
                break;
            case R.id.textRegister:
                break;
        }
    }

    //用于验证账号密码是否正确
    private void compareLoginInformation() {
        /**
         * 数据库中还没有账号密码等信息,本次模拟账号密码都正确的情况
         * */
        Toast.makeText(this, "成功登陆", Toast.LENGTH_LONG).show();
    }

    //使用文本监听器来检验手机号码输入是否合法
    TextWatcher editPhoneNumberWacher = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void afterTextChanged(Editable editable) {
            String inputStr = editable.toString().trim();
            if (!TextUtils.isEmpty(inputStr) && inputStr.getBytes().length == 11) {
                isPhoneNumberOk = true;
            } else {
                isPhoneNumberOk = false;

            }
            setButtonEnable();
        }
    };
    //使用文本监听器来检验密码输入是否合法
    TextWatcher editPasswordWacher = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void afterTextChanged(Editable editable) {
            String inputStr = editable.toString().trim();
            if (!TextUtils.isEmpty(inputStr) && inputStr.getBytes().length >= 6) {
                isPasswordOk = true;
            } else {
                isPasswordOk = false;

            }
            setButtonEnable();
        }
    };

    //当两个输入项格式都合法时 button才可以点击
    private void setButtonEnable() {
        if (isPasswordOk && isPhoneNumberOk) {
            buttonLogin.setBackgroundColor(Color.parseColor("#00BB00"));
            buttonLogin.setTextColor(Color.parseColor("#FFFFFF"));
            buttonLogin.setEnabled(true);
        } else {
            buttonLogin.setEnabled(false);
            buttonLogin.setBackgroundColor(Color.parseColor("#E0E0E0"));
        }
    }
}


总结与反思:

1、为什么要在onCreate中将登陆按钮设置为可点击?

不这么做的话你会发现账号密码还原后,登陆按钮是不可点击的,因为在onCreate中我们已经将登陆按钮的两个控制器都设置为false,而文本监听器是要监听到文本改变才会执行的,还原的账号密码不算认为改变,所以登陆控制按钮的控制器也无法设置为真,登陆按钮也就不可点击

2、为啥账号密码明文保存?

因为懒

啊 对了 程序中一些代码可能没用过Butterknife插件的人看不懂,这个插件大致作用就是快速注入view,直白点就是不用我们自己寻找view(还记得当初因为没寻找id程序一直报空指针的日子吗?),这个插件可以一键生成我们需要注册的id和点击事件,非常nice哦

下一篇会讲使用第三方提供的验证码来进行注册。。see you