因爲項目中大部分界面都有一個後退鍵和一個標題欄,爲避免代碼冗雜以及便於利用,咱們能夠將後推薦和標題欄單獨抽取出來定義一個標題欄佈局,在 res/layout 目錄下新建一個 Layout resource file ,Root element 選用 RelativeLayoutjava
具體代碼以下:android
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/title_bar" android:layout_width="match_parent" android:layout_height="50dp" android:background="@android:color/transparent"> <TextView android:id="@+id/tv_back" android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentLeft="true" android:background="@drawable/go_back_selector" /> <TextView android:id="@+id/tv_main_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:textColor="@android:color/white" android:textSize="20sp" /> </RelativeLayout>
將圖片導入 drawable 目錄下,在 activity 包下建立 RegisterActivity ,修改 activity_register.xml 爲 LinearLayout 佈局算法
具體代碼以下:數組
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_register" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/register_bg" android:orientation="vertical" tools:context="cn.edu.lt.android.boxueguapp.activity.RegisterActivity"> <include layout="@layout/main_title_bar"></include><!--引入標題欄--> <ImageView android:layout_width="70dp" android:layout_height="70dp" android:layout_gravity="center_horizontal" android:layout_marginTop="25dp" android:src="@drawable/default_icon" /> <EditText android:id="@+id/et_username" android:layout_width="fill_parent" android:layout_height="48dp" android:layout_marginLeft="35dp" android:layout_marginRight="35dp" android:layout_marginTop="35dp" android:background="@drawable/register_user_name_bg" android:drawableLeft="@drawable/user_name_icon" android:drawablePadding="10dp" android:gravity="center_vertical" android:hint="請輸入用戶名" android:paddingLeft="8dp" android:singleLine="true" android:textColor="#000000" android:textColorHint="#a3a3a3" android:textSize="14sp" /> <EditText android:id="@+id/et_pwd" android:layout_width="fill_parent" android:layout_height="48dp" android:layout_marginLeft="35dp" android:layout_marginRight="35dp" android:background="@drawable/register_psw_bg" android:drawableLeft="@drawable/psw_icon" android:drawablePadding="10dp" android:gravity="center_vertical" android:hint="請輸入密碼" android:inputType="textPassword" android:paddingLeft="8dp" android:singleLine="true" android:textColor="#000000" android:textColorHint="#a3a3a3" android:textSize="14sp" /> <EditText android:id="@+id/et_pwd_again" android:layout_width="fill_parent" android:layout_height="48dp" android:layout_marginLeft="35dp" android:layout_marginRight="35dp" android:background="@drawable/register_psw_again_bg" android:drawableLeft="@drawable/psw_icon" android:drawablePadding="10dp" android:gravity="center_vertical" android:hint="請再次輸入密碼" android:inputType="textPassword" android:paddingLeft="8dp" android:singleLine="true" android:textColor="#000000" android:textColorHint="#a3a3a3" android:textSize="14sp" /> <Button android:id="@+id/btn_register" android:layout_width="fill_parent" android:layout_height="40dp" android:layout_gravity="center_horizontal" android:layout_marginLeft="35dp" android:layout_marginRight="35dp" android:layout_marginTop="15dp" android:background="@drawable/register_selector" android:text="註冊" android:textColor="@android:color/white" android:textSize="18sp" /> </LinearLayout>
因爲註冊登陸涉及密碼,咱們須要對用戶的密碼進行 MD5 算法加密,MD5 的全稱是 Message-Digest Algorithm 5(信息--摘要算法),MD5 算法簡單來講就是把任意長度的字符串變換成固定長度(一般是128位)的16進制字符串,且此算法不可逆。咱們新建一個 utils 包,在此包下建立 MD5 加密工具類 MD5Utils ,具體代碼以下:app
package cn.edu.lt.android.boxueguapp.utils; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * Created by lt on 2017/12/26. */ public class MD5Utils { /** * md5加密算法 * @param text * @return */ public static String md5(String text){ try { MessageDigest digest = MessageDigest.getInstance("md5");//獲取數據指紋對象 byte[] result = digest.digest(text.getBytes());//字節數組 StringBuilder sb = new StringBuilder();//16進制轉換 for (byte b :result){//獲取全部字節進行轉換 int number = b & 0xff;//使用『與算法』,java使用unicode字符,因此每一個字符佔位兩個,則須要與兩位16進制最大值進行與運算,獲取number值 String hex = Integer.toHexString(number);//number值轉換字符串 if (hex.length()==1){//若轉換後的字符長度等於1則進行字符串拼接 sb.append("0" + hex); }else { sb.append(hex); } } return sb.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return "";//發送異常return空字符串 } } }
完成了註冊頁面的佈局與 MD5 工具類後,進行註冊界面的邏輯編寫。咱們在註冊界面點擊註冊按鈕後,須要獲取用戶名,用戶密碼和再次確認密碼,當兩次密碼相同時,將用戶名和密碼(通過 MD5 加密)保存到 SharedPreferences 中,同時當註冊成功以後須要將用戶名傳遞到登陸界面中。編輯器
具體代碼以下:ide
package cn.edu.lt.android.boxueguapp.activity; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Color; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; import cn.edu.lt.android.boxueguapp.R; import cn.edu.lt.android.boxueguapp.utils.MD5Utils; public class RegisterActivity extends AppCompatActivity { //提取全局變量:Ctrl+Alt+F //標題 private TextView tv_main_title; //返回按鈕 private TextView tv_back; //註冊按鈕 private Button btn_register; //帳號、密碼、再次輸入的密碼的控件 private EditText et_user_name,et_psw,et_psw_again; //帳號、密碼、再次輸入的密碼的控件的獲取值 private String userName,psw,pswAgain; //標題佈局 private RelativeLayout rl_title_bar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); init(); } private void init() { //從main_title_bar.xml頁面佈局中獲取對應的UI控件 tv_main_title = (TextView) findViewById(R.id.tv_main_title); tv_main_title.setText("註冊"); tv_back = (TextView) findViewById(R.id.tv_back); rl_title_bar = (RelativeLayout) findViewById(R.id.title_bar); rl_title_bar.setBackgroundColor(Color.TRANSPARENT); //從activity_register.xml頁面佈局中得到對應的UI控件 btn_register=(Button) findViewById(R.id.btn_register); et_user_name=(EditText) findViewById(R.id.et_username); et_psw=(EditText) findViewById(R.id.et_pwd); et_psw_again=(EditText) findViewById(R.id.et_pwd_again); tv_back.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { RegisterActivity.this.finish(); } }); btn_register.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //獲取輸入在相應控件中的字符串 getEditString(); //判斷輸入框內容 if(TextUtils.isEmpty(userName)){ Toast.makeText(RegisterActivity.this, "請輸入用戶名", Toast.LENGTH_SHORT).show(); return; }else if(TextUtils.isEmpty(psw)){ Toast.makeText(RegisterActivity.this, "請輸入密碼", Toast.LENGTH_SHORT).show(); return; }else if(TextUtils.isEmpty(pswAgain)){ Toast.makeText(RegisterActivity.this, "請再次輸入密碼", Toast.LENGTH_SHORT).show(); return; }else if(!psw.equals(pswAgain)){ Toast.makeText(RegisterActivity.this, "輸入兩次的密碼不同", Toast.LENGTH_SHORT).show(); return; }else if(isExistUserName(userName)){ Toast.makeText(RegisterActivity.this, "此帳戶名已經存在", Toast.LENGTH_SHORT).show(); return; }else{ Toast.makeText(RegisterActivity.this, "註冊成功", Toast.LENGTH_SHORT).show(); //把帳號、密碼和帳號標識保存到sp裏面 saveRegisterInfo(userName, psw); //註冊成功後把帳號傳遞到LoginActivity.java中 Intent data =new Intent(); data.putExtra("userName", userName); setResult(RESULT_OK, data); //RESULT_OK爲Activity系統常量,狀態碼爲-1,表示此頁面下的內容操做成功將data返回到上一頁面,若是是用back返回過去的則不存在用setResult傳遞data值 RegisterActivity.this.finish(); } } }); } /** * 獲取控件中的字符串 */ private void getEditString(){ userName=et_user_name.getText().toString().trim(); psw=et_psw.getText().toString().trim(); pswAgain=et_psw_again.getText().toString().trim(); } /** *從SharedPreferences中讀取輸入的用戶名,判斷SharedPreferences中是否有此用戶名 */ private boolean isExistUserName(String userName){ boolean has_userName=false; SharedPreferences sp=getSharedPreferences("loginInfo", MODE_PRIVATE); String spPsw=sp.getString(userName, "");//傳入用戶名獲取密碼 if(!TextUtils.isEmpty(spPsw)) {//若是密碼不爲空則確實保存過這個用戶名 has_userName=true; } return has_userName; } /** * 保存帳號和密碼到SharedPreferences中 */ private void saveRegisterInfo(String userName,String psw){ String md5Psw= MD5Utils.md5(psw);//把密碼用MD5加密 //loginInfo表示文件名 SharedPreferences sp=getSharedPreferences("loginInfo", MODE_PRIVATE); SharedPreferences.Editor editor=sp.edit();//獲取編輯器 //以用戶名爲key,密碼爲value保存在SharedPreferences中 editor.putString(userName, md5Psw); editor.commit();//提交修改 } }
接着編寫登陸界面的佈局,同理引入圖片至 drawable 目錄下,在 activity 包下建立 LoginActivity ,修改 activity_login.xml 爲 LinearLayout 佈局工具
具體代碼以下:佈局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/login_bg" tools:context="cn.edu.lt.android.boxueguapp.activity.LoginActivity" android:orientation="vertical"> <include layout="@layout/main_title_bar"></include> <ImageView android:id="@+id/iv_head" android:layout_width="70dp" android:layout_height="70dp" android:layout_gravity="center_horizontal" android:layout_marginTop="25dp" android:src="@drawable/default_icon" /> <EditText android:id="@+id/et_user_name" android:layout_width="fill_parent" android:layout_height="48dp" android:layout_marginTop="35dp" android:layout_marginLeft="35dp" android:layout_marginRight="35dp" android:layout_gravity="center_horizontal" android:background="@drawable/login_user_name_bg" android:drawableLeft="@drawable/user_name_icon" android:drawablePadding="10dp" android:paddingLeft="8dp" android:gravity="center_vertical" android:hint="請輸入用戶名" android:singleLine="true" android:textColor="#000000" android:textColorHint="#a3a3a3" android:textSize="14sp" /> <EditText android:id="@+id/et_psw" android:layout_width="fill_parent" android:layout_height="48dp" android:layout_gravity="center_horizontal" android:layout_marginLeft="35dp" android:layout_marginRight="35dp" android:background="@drawable/login_psw_bg" android:drawableLeft="@drawable/psw_icon" android:drawablePadding="10dp" android:paddingLeft="8dp" android:hint="請輸入密碼" android:inputType="textPassword" android:singleLine="true" android:textColor="#000000" android:textColorHint="#a3a3a3" android:textSize="14sp" /> <Button android:id="@+id/btn_login" android:layout_width="fill_parent" android:layout_height="40dp" android:layout_marginTop="15dp" android:layout_marginLeft="35dp" android:layout_marginRight="35dp" android:layout_gravity="center_horizontal" android:background="@drawable/register_selector" android:text="登陸" android:textColor="@android:color/white" android:textSize="18sp" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginTop="8dp" android:layout_marginLeft="35dp" android:layout_marginRight="35dp" android:gravity="center_horizontal" android:orientation="horizontal" > <TextView android:id="@+id/tv_register" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_horizontal" android:padding="8dp" android:text="當即註冊" android:textColor="@android:color/white" android:textSize="14sp" /><!--layout_weight="1" layout_width="0dp"實現均分效果--> <TextView android:id="@+id/tv_find_psw" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_horizontal" android:padding="8dp" android:text="找回密碼?" android:textColor="@android:color/white" android:textSize="14sp" /> </LinearLayout> </LinearLayout>
完成登陸界面佈局後,最後咱們實現登陸界面的邏輯代碼,當點擊登陸按鈕時,需先判斷用戶名和密碼是否爲空,若爲空則提示請輸入用戶名和密碼,若不爲空則獲取用戶輸入的用戶名,因爲本項目用的是本地數據,所以根據用戶名在 SharedPreferences 中查詢是否有對應的密碼,如有對應的密碼且與用戶輸入的密碼(需 MD5 加密)比對一致,則登陸成功ui
具體代碼以下:
package cn.edu.lt.android.boxueguapp.activity; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import cn.edu.lt.android.boxueguapp.MainActivity; import cn.edu.lt.android.boxueguapp.R; import cn.edu.lt.android.boxueguapp.utils.MD5Utils; public class LoginActivity extends AppCompatActivity { private TextView tv_main_title; private TextView tv_back,tv_register,tv_find_psw; private Button btn_login; private String userName,psw,spPsw; private EditText et_user_name,et_psw; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); //設置此界面爲豎屏 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); init(); } /** * 獲取界面控件 */ private void init(){ tv_main_title=(TextView) findViewById(R.id.tv_main_title); tv_main_title.setText("登陸"); tv_back=(TextView) findViewById(R.id.tv_back); tv_register=(TextView) findViewById(R.id.tv_register); tv_find_psw= (TextView) findViewById(R.id.tv_find_psw); btn_login=(Button) findViewById(R.id.btn_login); et_user_name=(EditText) findViewById(R.id.et_user_name); et_psw=(EditText) findViewById(R.id.et_psw); tv_back.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { LoginActivity.this.finish(); } }); //當即註冊控件的點擊事件 tv_register.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent(LoginActivity.this,RegisterActivity.class); startActivityForResult(intent, 1); } }); //找回密碼控件的點擊事件 tv_find_psw.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //跳轉到找回密碼界面(此頁面暫未建立) } }); //登陸按鈕的點擊事件 btn_login.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { userName=et_user_name.getText().toString().trim(); psw=et_psw.getText().toString().trim(); String md5Psw= MD5Utils.md5(psw);//對當前用戶輸入的密碼進行MD5加密再進行比對判斷 spPsw=readPsw(userName);//從SharedPreferences中根據用戶名讀取密碼 if(TextUtils.isEmpty(userName)){ Toast.makeText(LoginActivity.this, "請輸入用戶名", Toast.LENGTH_SHORT).show(); return; }else if(TextUtils.isEmpty(psw)){ Toast.makeText(LoginActivity.this, "請輸入密碼", Toast.LENGTH_SHORT).show(); return; }else if(md5Psw.equals(spPsw)){ Toast.makeText(LoginActivity.this, "登陸成功", Toast.LENGTH_SHORT).show(); //保存登陸狀態 saveLoginStatus(true, userName); //登陸成功後關閉此頁面進入主頁 Intent data=new Intent(); data.putExtra("isLogin",true); setResult(RESULT_OK,data); LoginActivity.this.finish(); startActivity(new Intent(LoginActivity.this, MainActivity.class)); return; }else if((spPsw!=null&&!TextUtils.isEmpty(spPsw)&&!md5Psw.equals(spPsw))){ Toast.makeText(LoginActivity.this, "輸入的用戶名和密碼不一致", Toast.LENGTH_SHORT).show(); return; }else{ Toast.makeText(LoginActivity.this, "此用戶名不存在", Toast.LENGTH_SHORT).show(); } } }); } /** *從SharedPreferences中根據用戶名讀取密碼 */ private String readPsw(String userName){ SharedPreferences sp=getSharedPreferences("loginInfo", MODE_PRIVATE); return sp.getString(userName , ""); } /** *保存登陸狀態和登陸用戶名到SharedPreferences中 */ private void saveLoginStatus(boolean status,String userName){ //loginInfo表示文件名 SharedPreferences sp=getSharedPreferences("loginInfo", MODE_PRIVATE); SharedPreferences.Editor editor=sp.edit();//獲取編輯器 editor.putBoolean("isLogin", status);//存入boolean類型的登陸狀態 editor.putString("loginUserName", userName);//存入登陸狀態時的用戶名 editor.commit();//提交修改 } /** * 註冊成功的數據返回至此 * @param requestCode * @param resultCode * @param data */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(data!=null){ //從註冊界面傳遞過來的用戶名 String userName =data.getStringExtra("userName"); if(!TextUtils.isEmpty(userName)){ et_user_name.setText(userName); //設置光標的位置 et_user_name.setSelection(userName.length()); } } } }
將歡迎界面的下一個界面從主頁修改成登陸界面,具體代碼以下:
Intent intent = new Intent(SplashActivity.this, MainActivity.class); 改成 Intent intent = new Intent(SplashActivity.this, LoginActivity.class);