你们好,给你们带来AndroidStudio制做登陆和注册功能的实现,界面的布局介绍
的概述,但愿大家喜欢java
Success is connecting with the world and making people feel. - 《名扬四海》
android
当咱们面临制做登陆和注册功能的实现时,咱们须要先设计登陆界面的布局和注册界面的布局,作到有完整的思路时才开始实现其功能效果会更好。算法
咱们须要作个标题栏,登录界面,实现登录界面的功能代码块,注册界面,实现测试界面的功能模块便可完成。数组
每一个APP都基本上有个标题栏,便是显示标题,标题栏的两侧大多数都有一个返回建。那么标题栏便是一个返回键和一个标题栏的制做布局。安全
为了不大多数代码的冗杂,咱们把这个标题栏的制做布局独立起来,标题的显示咱们能够在每块主题模块上,用setText()
方法来显示不一样的标题。app
接下来咱们建立main_title_bar.xml
布局文件:
具体代码以下:编辑器
<?xml version="1.0" encoding="utf-8"?> <!--这里代码的是建立一个标题栏,左边是返回键--> <!--咱们设置RelativeLayout布局,id = "title_bar"--> <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来显示,id : tv_back , tv_main_title --> <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"/> <!--其中android:background="@drawable/go_back_selector"为点击回退键时,会变化效果,其实就是一个点击更换个图片而已。--> <!--咱们先用这种老方法,接下来之后的文章才作代码优化效果--> </RelativeLayout>
如今标题栏布局作好了,咱们须要了解怎么换图片,就是在android:background="@drawable/go_back_selector"
,其实就是在drawable中建立这个go_back_selector.xml
文件而已,用到了android:state_pressed="true"
这个属性,当点击时就是变化的图片效果,记住state_pressed就OK。ide
建立登陆界面,咱们须要标题栏显示“登陆”,那么就要经过
咱们须要设计想好美化登陆界面,须要如下图片:登陆背景图片login_bg.png
,默认的头像图片default_icon
,输入用户名的背景图片login_user_name_bg
,在用户名前须要一个小标图user_name_icon
,同理,输入密码框须要图片有login_psw_bg,psw_icon
,按钮须要图片加以美观register_selector
,根据须要的图片可自行制做。布局
建立activity_login.xml布局文件,具体代码以下:
<?xml version="1.0" encoding="utf-8"?> <!--登陆界面,用LinearLayout--> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/login_bg" android:orientation="vertical"> <!--标题栏--> <include layout="@layout/main_title_bar"></include> <!--显示头像,记得加入id iv_head --> <ImageView android:id="@+id/iv_head" android:layout_width="70dp" android:layout_height="70dp" android:layout_marginTop="25dp" android:layout_gravity="center_horizontal" android:background="@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:gravity="center_vertical" 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"/> <!--显示tv register , find_psw --> <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>
建立注册界面,咱们须要标题栏显示“注册”,那么就要经过
建立activity_register.xml布局文件,具体代码以下:
<?xml version="1.0" encoding="utf-8"?> <!--注册界面--> <!--这里的布局放置是: 1 个 ImageView 控件,用于显示用户头像;3 个 EditText 控件,用于输入用户名、密码、再次输入密码;1 个 Button 控件为注册按钮--> <!--修改 activity_register.xml 为 LinearLayout 布局--> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/activity_register" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/register_bg" android:orientation="vertical"> <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_user_name" android:layout_width="fill_parent" android:layout_height="48dp" android:layout_gravity="center_horizontal" 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_psw" android:layout_width="fill_parent" android:layout_gravity="center_horizontal" 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:hint="请输入密码" android:inputType="textPassword" android:paddingLeft="8dp" android:singleLine="true" android:textColor="#000000" android:textColorHint="#a3a3a3" android:textSize="14sp"/> <EditText android:id="@+id/et_psw_again" 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/register_psw_again_bg" android:drawableLeft="@drawable/psw_icon" android:drawablePadding="10dp" 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 为 Message-Digest Algorithm 5(信息--摘要算法),记住几个要点就能够了。
具体代码以下:
package cn.edu.gdmec.android.androidstudiodemo.utils; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class MD5Utils { //md5 加密算法 public static String md5(String text) { MessageDigest digest = null; try { digest = MessageDigest.getInstance("md5"); // 数组 byte[] result -> digest.digest( ); 文本 text.getBytes(); byte[] result = digest.digest(text.getBytes()); //建立StringBuilder对象 而后建议StringBuffer,安全性高 //StringBuilder sb = new StringBuilder(); StringBuffer sb = new StringBuffer(); // result数组,digest.digest ( ); -> text.getBytes(); // for 循环数组byte[] result; for (byte b : result){ // 0xff 为16进制 int number = b & 0xff; // number值 转换 字符串 Integer.toHexString( ); String hex = Integer.toHexString(number); if (hex.length() == 1){ sb.append("0"+hex); }else { sb.append(hex); } } //sb StringBuffer sb = new StringBuffer();对象实例化 return sb.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); //发送异常return空字符串 return ""; } } }
完成注册页面的布局与 MD5 工具类后,进行注册界面的逻辑编写。
当在注册界面点击注册按钮后,须要获取用户名,用户密码和再次确认密码,当两次密码相同时,将用户名和密码(通过 MD5 加密)保存到 SharedPreferences 中,同时当注册成功后,须要将用户名传递到登陆界面中。
RegisterActivity.java具体代码以下:
package cn.edu.gdmec.android.androidstudiodemo; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.graphics.Color; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; 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.gdmec.android.androidstudiodemo.utils.MD5Utils; public class RegisterActivity extends AppCompatActivity { 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); //设置此界面为竖屏 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); init(); } private void init() { //从main_title_bar.xml 页面布局中获取对应的UI控件 tv_main_title=findViewById(R.id.tv_main_title); tv_main_title.setText("注册"); tv_back=findViewById(R.id.tv_back); //布局根元素 rl_title_bar=findViewById(R.id.title_bar); rl_title_bar.setBackgroundColor(Color.TRANSPARENT); //从activity_register.xml 页面中获取对应的UI控件 btn_register=findViewById(R.id.btn_register); et_user_name=findViewById(R.id.et_user_name); et_psw=findViewById(R.id.et_psw); et_psw_again=findViewById(R.id.et_psw_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; /** *从SharedPreferences中读取输入的用户名,判断SharedPreferences中是否有此用户名 */ }else if(isExistUserName(userName)){ Toast.makeText(RegisterActivity.this, "此帐户名已经存在", Toast.LENGTH_SHORT).show(); return; }else{ Toast.makeText(RegisterActivity.this, "注册成功", Toast.LENGTH_SHORT).show(); //把帐号、密码和帐号标识保存到sp里面 /** * 保存帐号和密码到SharedPreferences中 */ saveRegisterInfo(userName, psw); //注册成功后把帐号传递到LoginActivity.java中 // 返回值到loginActivity显示 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; //mode_private SharedPreferences sp = getSharedPreferences( ); // "loginInfo", MODE_PRIVATE SharedPreferences sp=getSharedPreferences("loginInfo", MODE_PRIVATE); //获取密码 String spPsw=sp.getString(userName, "");//传入用户名获取密码 //若是密码不为空则确实保存过这个用户名 if(!TextUtils.isEmpty(spPsw)) { has_userName=true; } return has_userName; } /** * 保存帐号和密码到SharedPreferences中SharedPreferences */ private void saveRegisterInfo(String userName,String psw){ String md5Psw = MD5Utils.md5(psw);//把密码用MD5加密 //loginInfo表示文件名, mode_private SharedPreferences sp = getSharedPreferences( ); SharedPreferences sp=getSharedPreferences("loginInfo", MODE_PRIVATE); //获取编辑器, SharedPreferences.Editor editor -> sp.edit(); SharedPreferences.Editor editor=sp.edit(); //以用户名为key,密码为value保存在SharedPreferences中 //key,value,如键值对,editor.putString(用户名,密码); editor.putString(userName, md5Psw); //提交修改 editor.commit(); editor.commit(); } }
完成登陆界面布局后,来实现登陆界面的逻辑代码。
当点击登陆按钮时,需判断用户名和密码是否为空。
若为空,则提示请输入用户名或密码,这里的判断事项比较一开始凌乱,须要细细品味;若不为空,则获取用户输入的用户名,因为用的是本地数据,须要根据用户名在 SharedPreferences 中查询是否有对应的密码,如有对应的密码且与用户输入的密码(需经过 MD5 加密)比对一致状况,则登陆成功。
LoginActivity.java具体代码以下:
package cn.edu.gdmec.android.androidstudiodemo; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; 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.gdmec.android.androidstudiodemo.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() { //从main_title_bar中获取的id tv_main_title=findViewById(R.id.tv_main_title); tv_main_title.setText("登陆"); tv_back=findViewById(R.id.tv_back); //从activity_login.xml中获取的 tv_register=findViewById(R.id.tv_register); tv_find_psw=findViewById(R.id.tv_find_psw); btn_login=findViewById(R.id.btn_login); et_user_name=findViewById(R.id.et_user_name); et_psw=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) { //开始登陆,获取用户名和密码 getText().toString().trim(); userName=et_user_name.getText().toString().trim(); psw=et_psw.getText().toString().trim(); //对当前用户输入的密码进行MD5加密再进行比对判断, MD5Utils.md5( ); psw 进行加密判断是否一致 String md5Psw= MD5Utils.md5(psw); // md5Psw ; spPsw 为 根据从SharedPreferences中用户名读取密码 // 定义方法 readPsw为了读取用户名,获得密码 spPsw=readPsw(userName); // TextUtils.isEmpty 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; // md5Psw.equals(); 判断,输入的密码加密后,是否与保存在SharedPreferences中一致 }else if(md5Psw.equals(spPsw)){ //一致登陆成功 Toast.makeText(LoginActivity.this, "登陆成功", Toast.LENGTH_SHORT).show(); //保存登陆状态,在界面保存登陆的用户名 定义个方法 saveLoginStatus boolean 状态 , userName 用户名; saveLoginStatus(true, userName); //登陆成功后关闭此页面进入主页 Intent data=new Intent(); //datad.putExtra( ); name , value ; data.putExtra("isLogin",true); //RESULT_OK为Activity系统常量,状态码为-1 // 表示此页面下的内容操做成功将data返回到上一页面,若是是用back返回过去的则不存在用setResult传递data值 setResult(RESULT_OK,data); //销毁登陆界面 LoginActivity.this.finish(); //跳转到主界面,登陆成功的状态传递到 MainActivity 中 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){ //getSharedPreferences("loginInfo",MODE_PRIVATE); //"loginInfo",mode_private; MODE_PRIVATE表示能够继续写入 SharedPreferences sp=getSharedPreferences("loginInfo", MODE_PRIVATE); //sp.getString() userName, ""; return sp.getString(userName , ""); } /** *保存登陆状态和登陆用户名到SharedPreferences中 */ private void saveLoginStatus(boolean status,String userName){ //saveLoginStatus(true, userName); //loginInfo表示文件名 SharedPreferences sp=getSharedPreferences("loginInfo", MODE_PRIVATE); SharedPreferences sp=getSharedPreferences("loginInfo", MODE_PRIVATE); //获取编辑器 SharedPreferences.Editor editor=sp.edit(); //存入boolean类型的登陆状态 editor.putBoolean("isLogin", status); //存入登陆状态时的用户名 editor.putString("loginUserName", userName); //提交修改 editor.commit(); } /** * 注册成功的数据返回至此 * @param requestCode 请求码 * @param resultCode 结果码 * @param data 数据 */ @Override //显示数据, onActivityResult //startActivityForResult(intent, 1); 从注册界面中获取数据 //int requestCode , int resultCode , Intent data // LoginActivity -> startActivityForResult -> onActivityResult(); protected void onActivityResult(int requestCode, int resultCode, Intent data) { //super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data); if(data!=null){ //是获取注册界面回传过来的用户名 // getExtra().getString("***"); String userName=data.getStringExtra("userName"); if(!TextUtils.isEmpty(userName)){ //设置用户名到 et_user_name 控件 et_user_name.setText(userName); //et_user_name控件的setSelection()方法来设置光标位置 et_user_name.setSelection(userName.length()); } } } }
如作了效果,须要在清单文件中实现该类,文件的跳转,能够本身了解一下。主要介绍注册模块,登陆模块。里面的注解我写的若是有不全的或者错误点,能够联系讨论。
接下来你看到如上代码有点多,那么咱们能够进行代码的优化来减小代码量。
Android
&Java
知识点,有兴趣能够继续关注