本来这次应该是做历史模块的,但是因为接口是从网络上获取的,而聚合数据是需要钱才可以用多个免费接口(这点我就很想吐槽,一个账户只能用一个免费接口,而且每天只能用100次,太坑了),于是我就想先到其他网站看看有没有免费的接口。本次就将这个程序完善的更加像一个应用吧,我计划加入登陆注册功能,包含验证码登陆,第三方登陆,但是没有后台,所以数据只能存在本地的sqlite数据库中,不过这次只讲登陆中的记住密码以及验证功能,先上效果图
第一部分:布局实现
布局效果图:
布局代码:
<?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;2、给账号密码加入文本监听器,当然,还需要绑定事件,这里就不一一写了,最后会贴出总代码private Boolean isPasswordOk;
//使用文本监听器来检验手机号码输入是否合法 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