安卓学习笔记3——登录界面UI
- 一、登录界面UI
-
- 1、根据需求写UI
- 2、主活动
- 3、主活动调用的读写文件的工具类
- 4、效果展示
- 二、总结与改进
-
- 不足:
-
- 1、密码分割采用字符串:当密码和用户名包含该字符串时,无法分割
- 2、文件路径是绝对路径:
- 3、向外部存储写入数据:
一、登录界面UI
注:只做UI不做服务器后端,使用android studio3.5
1、根据需求写UI
- 采用线性布局内嵌相对布局
- 线性布局垂直排列
- 内部控件一共四个:edittext2个,Button一个,checkbox一个
- 正常为控件设置宽高、文本、文本大小(dp和sp的区别)
- password文本框,使用inputType属性显示密文
- button设置onclick属性,按键事件监听可调起方法login
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<EditText
android:id="@+id/user_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入用户名"
android:textSize="25dp"
/>
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入密码"
android:inputType="textPassword"
android:textSize="25dp"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="20dp">
<CheckBox
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="记住用户名和密码"
/>
<Button
android:onClick="login"
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="登录"
android:layout_alignParentRight="true"
android:layout_marginRight="20dp"
android:textSize="25dp"
/>
</RelativeLayout>
</LinearLayout>
2、主活动
- 根据findViewById和id找到对应地控件,并将返回值根据类型向下转型,传给私有成员变量
- 写按键监听调用方法login;按键按下,获取用户名和密码,Toast提示勾选“记住密码”;将密码写入文件。
- 启动活动时,读取文件并显示
package com.example.loginui;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
import java.io.File;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
private EditText et_username;
private Button bt;
private EditText et_password ;
private CheckBox checkBox;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_username=(EditText) findViewById(R.id.user_name);
bt =(Button) findViewById(R.id.button1);
et_password = (EditText) findViewById(R.id.password);
checkBox=(CheckBox) findViewById(R.id.checkbox);
Map<String,String> maps=saveInfoUtils.readInfo();
if (maps!=null){
String name=maps.get("name");
String pwd=maps.get("pwd");
et_username.setText(name);
et_password.setText(pwd);
}
}
public void login(View view){
String name=et_username.getText().toString().trim();
String pass=et_password.getText().toString().trim();
if (TextUtils.isEmpty(name)||TextUtils.isEmpty(pass) ){
Toast.makeText(MainActivity.this,"用户名或密码不能为空",Toast.LENGTH_SHORT).show();
}
else{
if(checkBox.isChecked()){
// 存密码
if(!saveInfoUtils.saveInfo(name,pass)){
System.out.println("密码保存失败");
}
System.out.println("开始登录");
}
else{
Toast.makeText(MainActivity.this,"请勾选记住密码",Toast.LENGTH_SHORT).show();
}
}
}
}
3、主活动调用的读写文件的工具类
saveInfoUtils.java
使用java IO操作,记得catch 异常
- 写入文件:文件输出流fos.write(str.getBytes())
- 读取文件:BufferedReader buf=new BufferedReader(new InputStreamReader(fis))
package com.example.loginui;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
public class saveInfoUtils {
public static boolean saveInfo(String user,String pwd){
try{
String str=user+","+pwd;
File file=new File("data/data/com.example.loginui/userinfo.txt");
FileOutputStream fos=new FileOutputStream(file);
fos.write(str.getBytes());
fos.close();
return true;
}
catch(Exception ex){
ex.printStackTrace();
return false;
}
}
public static Map<String,String> readInfo(){
Map<String,String> maps=new HashMap<String,String>();
try{
File file=new File("data/data/com.example.loginui/userinfo.txt");
FileInputStream fis=new FileInputStream(file);
BufferedReader buf=new BufferedReader(new InputStreamReader(fis));
String[] content=buf.readLine().split(",");
maps.put("name",content[0]);
maps.put("pwd",content[1]);
fis.close();
return maps;
}
catch(Exception ex){
ex.printStackTrace();
return null;
}
}
}
4、效果展示

二、总结与改进
不足:
1、密码分割采用字符串:当密码和用户名包含该字符串时,无法分割
- 使用SharedPreferences 接口完成配置信息存取
code
写入配置文件
SharedPreferences sp=getSharedPreferences("config",0);
SharedPreferences.Editor editor=sp.edit();
editor.putString("name",name);
editor.putString("pwd",pass);
editor.commit();
读取配置文件
SharedPreferences config=getSharedPreferences("config",0);
et_username.setText(config.getString("name",""));//前面为key,后面为默认值
et_password.setText(config.getString("pwd",""));
效果:可以添加任意字符
- 使用SharedPreferences 记录复选框的勾选状态
code
SharedPreferences config=getSharedPreferences("config",0);
et_username.setText(config.getString("name",""));
et_password.setText(config.getString("pwd",""));
checkBox.setChecked(config.getBoolean("ischeck",false));
SharedPreferences sp=getSharedPreferences("config",0);
SharedPreferences.Editor editor=sp.edit();
editor.putString("name",name);
editor.putString("pwd",pass);
// 存复选框状态
editor.putBoolean("ischeck",true);
editor.commit();
2、文件路径是绝对路径:
文件路径和读写操作可采用content的方法
- 通过content.openFileOutput()获取文件输出流,
- 通过content.openFileInput()获取文件输入流,
- 这种情况会自动在app目录下创建files文件夹,代码简化,逻辑更佳
saveInfo1方法
public static boolean saveInfo1(Context context,String user, String pwd){
try{
// String path=context.getFilesDir().getPath();
String str=user+","+pwd;
// File file=new File(path,"info.txt");
// FileOutputStream fos=new FileOutputStream(file);
FileOutputStream fos=context.openFileOutput("info.txt",0);
fos.write(str.getBytes());
fos.close();
return true;
}
catch(Exception ex){
ex.printStackTrace();
return false;
}
}
readInfo1方法
public static Map<String,String> readInfo1(Context context){
Map<String,String> maps=new HashMap<>();
try{
// String path=context.getFilesDir().getPath();
// File file=new File(path,"info.txt");
// FileInputStream fis=new FileInputStream(file);
FileInputStream fis= context.openFileInput("info.txt");
BufferedReader buf=new BufferedReader(new InputStreamReader(fis));
String[] content=buf.readLine().split(",");
maps.put("name",content[0]);
maps.put("pwd",content[1]);
fis.close();
return maps;
}
catch(Exception ex){
ex.printStackTrace();
return null;
}
}
3、向外部存储写入数据:
-
类:Enviroment:提供获取环境变量的途径;不采用路径硬编码
static File getExternalStorageDirectory()
- 清单文件申请权限,动态申请权限
- 判断SD卡是否可用 code
安卓学习笔记3——登录界面UI一、登录界面UI二、总结与改进
清单文件
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
新增动态获取权限:
Toast.makeText(MainActivity.this,"权限不足",Toast.LENGTH_SHORT).show();
int REQUEST_EXTERNAL_STORAGE = 1;
String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE
};
int permission = ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if(permission!= PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
MainActivity.this,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
判断sd卡是否可用:
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()){
//sd卡已挂载
}