安卓學習筆記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卡已挂載
}