Android项目实战登录&注册

智者不为愚者谋,勇者不为怯者死。这篇文章主要讲述Android项目实战登录& 注册相关的知识,希望能为你提供帮助。
由于项目中大部分界面都有一个后退键和一个标题栏,为避免代码冗杂以及便于利用,我们可以将后推荐和标题栏单独抽取出来定义一个标题栏布局,在 res/layout 目录下新建一个 Layout resource file ,Root element 选用 RelativeLayout
具体代码如下:

main_title_bar.xml < ?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 布局
具体代码如下:
activity_register.xml < ?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=https://www.songbingjia.com/android/" @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 算法加密,MD5 的全称是 Message-Digest Algorithm 5(信息--摘要算法),MD5 算法简单来说就是把任意长度的字符串变换成固定长度(通常是128位)的16进制字符串,且此算法不可逆。我们新建一个 utils 包,在此包下创建 MD5 加密工具类 MD5Utils ,具体代码如下:
MD5Utils 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 中,同时当注册成功之后需要将用户名传递到登录界面中。
具体代码如下:
RegisterActivity 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 =https://www.songbingjia.com/android/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 布局
具体代码如下:
activity_login.xml < ?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=https://www.songbingjia.com/android/" @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 加密)比对一致,则登录成功
具体代码如下:
LoginActivity 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=https://www.songbingjia.com/android/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()); } } }}

【Android项目实战登录& 注册】修改欢迎界面逻辑
将欢迎界面的下一个界面从主页修改为登录界面,具体代码如下:
SplashActivity Intent intent = new Intent(SplashActivity.this, MainActivity.class); 改为Intent intent = new Intent(SplashActivity.this, LoginActivity.class);


    推荐阅读