目錄
MainActivity.this 調用時加個參數MainActivity.this 就是context
UserInfoUtils.java 不硬編碼,改用context獲取目錄路徑
案例1:記住用戶名密碼
寫法1:純IO流方式,硬編碼
佈局:
<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:orientation="vertical"
tools:context=".MainActivity" >
<EditText
android:id="@+id/et_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="請輸入用戶名" />
<EditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:password="true"
android:hint="請輸入密碼" />
<RelativeLayout
android:layout_marginTop="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<CheckBox
android:id="@+id/cb_ischeck"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="記住密碼" />
<Button
android:onClick="login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="登錄"
/>
</RelativeLayout>
</LinearLayout>
主邏輯代碼:MainActivity.java
package com.example.login;
import java.util.Map;
import android.os.Bundle;
import android.app.Activity;
import android.text.TextUtils;
import android.view.Menu;
import android.view.TextureView;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
import com.example.login2.R;
public class MainActivity extends Activity {
private EditText et_name;
private EditText et_pwd;
private CheckBox cb_check;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_name = (EditText) findViewById(R.id.et_username);
et_pwd = (EditText) findViewById(R.id.et_password);
cb_check = (CheckBox) findViewById(R.id.cb_ischeck);
//讀取info.txt
Map<String,String> maps=UserInfoUtils.read();
if(maps!=null){
et_name.setText(maps.get("name"));
et_pwd.setText(maps.get("pwd"));
cb_check.setChecked(true);
}
}
public void login(View v){
String username = et_name.getText().toString().trim();
String pwd = et_pwd.getText().toString().trim();
if(TextUtils.isEmpty(username)||TextUtils.isEmpty(pwd)){
Toast.makeText(this, "用戶名或密碼不能爲空!", 0).show();
}else{
System.out.println("連接服務器中...");
if(cb_check.isChecked()){
boolean res = UserInfoUtils.saveInfo(username, pwd);
if(res){
Toast.makeText(this, "保存成功!", 0).show();
}else{
Toast.makeText(this, "保存失敗!", 0).show();
}
}else{
System.out.println("未保存密碼!");
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
工具類UserInfoUtils.java
package com.example.login;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
public class UserInfoUtils {
public static boolean saveInfo(String username,String pwd) {
try {
String result=username+"##"+pwd;
//創建文件(確定輸出位置)
File file=new File("/data/data/com.example.login2/info.txt");
//創建輸出流
FileOutputStream fos=new FileOutputStream(file);
//輸出(寫)文件
fos.write(result.getBytes());
fos.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static Map<String, String> read() {
try {
Map<String, String> maps=new HashMap<String, String>();
File file=new File("/data/data/com.example.login2/info.txt");
FileInputStream fis=new FileInputStream(file);
BufferedReader bfr=new BufferedReader(new InputStreamReader(fis));
String content=bfr.readLine();//讀一行
String[] splits = content.split("##");
maps.put("name",splits[0]);
maps.put("pwd", splits[1]);
fis.close();
return maps;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
第一次改進
寫法2:使用上下文獲取文件錄
上下文context就是this或者說MainActivity.this
String path = context.getFilesDir().getPath();//context就是MainActivity.this 調用此api,會自動幫我們在本項目包名目錄下創建一個專門的文件目錄files以供我們創建,存放,讀取文件到外存
MainActivity.this 調用時加個參數MainActivity.this 就是context
package com.example.login;
import java.util.Map;
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Menu;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
private EditText et_name;
private EditText et_pwd;
private CheckBox cb_check;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_name = (EditText) findViewById(R.id.et_username);
et_pwd = (EditText) findViewById(R.id.et_password);
cb_check = (CheckBox) findViewById(R.id.cb_ischeck);
// 讀取info.txt
Map<String, String> maps = UserInfoUtils.read(MainActivity.this);
if (maps != null) {
et_name.setText(maps.get("name"));
et_pwd.setText(maps.get("pwd"));
cb_check.setChecked(true);
}
}
public void login(View v) {
String username = et_name.getText().toString().trim();
String pwd = et_pwd.getText().toString().trim();
if (TextUtils.isEmpty(username) || TextUtils.isEmpty(pwd)) {
Toast.makeText(this, "用戶名或密碼不能爲空!", 0).show();
} else {
System.out.println("連接服務器中...");
if (cb_check.isChecked()) {
boolean res = UserInfoUtils.saveInfo(this, username, pwd);
if (res) {
Toast.makeText(this, "保存成功!", 0).show();
} else {
Toast.makeText(this, "保存失敗!", 0).show();
}
} else {
System.out.println("未保存密碼!");
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
UserInfoUtils.java 不硬編碼,改用context獲取目錄路徑
package com.example.login;
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;
import android.content.Context;
public class UserInfoUtils {
public static boolean saveInfo(Context context, String username,String pwd) {
try {
String path = context.getFilesDir().getPath();//幫我們在包名目錄下生成一個目錄files
System.out.println(path);
String result=username+"##"+pwd;
//創建文件(確定輸出位置)
File file=new File(path,"info.txt");
//創建輸出流
FileOutputStream fos=new FileOutputStream(file);
//輸出(寫)文件
fos.write(result.getBytes());
fos.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static Map<String, String> read(Context context) {
try {
Map<String, String> maps=new HashMap<String, String>();
String path = context.getFilesDir().getPath();
File file=new File(path,"info.txt");
FileInputStream fis=new FileInputStream(file);
BufferedReader bfr=new BufferedReader(new InputStreamReader(fis));
String content=bfr.readLine();//讀一行
String[] splits = content.split("##");
maps.put("name",splits[0]);
maps.put("pwd", splits[1]);
fis.close();
return maps;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
寫法3:徹底告別IO流
String path = context.getFilesDir().getPath();
File file=new File(path,"info.txt");
FileInputStream fis=new FileInputStream(file);上面3行可以縮減爲下面一行
FileInputStream fis = context.openFileInput("infoo.txt");
UserInfoUtils.java
package com.example.login;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import android.content.Context;
public class UserInfoUtils {
public static boolean saveInfo(Context context, String username,String pwd) {
try {
String result=username+"##"+pwd;
//創建輸出流
FileOutputStream fos=context.openFileOutput("infoo.txt",context.MODE_PRIVATE);
//輸出(寫)文件
fos.write(result.getBytes());
fos.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static Map<String, String> read(Context context) {
try {
Map<String, String> maps=new HashMap<String, String>();
/*String path = context.getFilesDir().getPath();
File file=new File(path,"info.txt");
FileInputStream fis=new FileInputStream(file);*/
//context特別強大,一下一行比上上面三行
FileInputStream fis = context.openFileInput("infoo.txt");
BufferedReader bfr=new BufferedReader(new InputStreamReader(fis));
String content=bfr.readLine();//讀一行
String[] splits = content.split("##");
maps.put("name",splits[0]);
maps.put("pwd", splits[1]);
fis.close();
return maps;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
其他不變
寫法4:寫到sdcard
加權限:android.permission.WRITE_EXTERNAL_STORAGE
原始方案下修改
UserInfoUtils.java
package com.example.login;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
public class UserInfoUtils {
public static boolean saveInfo(String username,String pwd) {
try {
String result=username+"##"+pwd;
//創建文件(確定輸出位置)
File file=new File("/mnt/sdcard/info2.txt");
//創建輸出流
FileOutputStream fos=new FileOutputStream(file);
//輸出(寫)文件
fos.write(result.getBytes());
fos.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static Map<String, String> read() {
try {
Map<String, String> maps=new HashMap<String, String>();
File file=new File("/mnt/sdcard/info2.txt");
FileInputStream fis=new FileInputStream(file);
BufferedReader bfr=new BufferedReader(new InputStreamReader(fis));
String content=bfr.readLine();//讀一行
String[] splits = content.split("##");
maps.put("name",splits[0]);
maps.put("pwd", splits[1]);
fis.close();
return maps;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
逍遙模擬器可能將sdcard砍掉了,因此eclipse裏查看不到
寫法5:寫到sdcard,Environment告別硬編碼
String sdpath = Environment.getExternalStorageDirectory().getPath();//獲取sdcard路徑
UserInfoUtils.java
package com.example.login;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import android.os.Environment;
public class UserInfoUtils {
public static boolean saveInfo(String username,String pwd) {
try {
String result=username+"##"+pwd;
//創建文件(確定輸出位置)
String sdpath = Environment.getExternalStorageDirectory().getPath();
File file=new File(sdpath,"info2.txt");
//創建輸出流
FileOutputStream fos=new FileOutputStream(file);
//輸出(寫)文件
fos.write(result.getBytes());
fos.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static Map<String, String> read() {
try {
Map<String, String> maps=new HashMap<String, String>();
String sdpath = Environment.getExternalStorageDirectory().getPath();
File file=new File(sdpath,"info2.txt");
FileInputStream fis=new FileInputStream(file);
BufferedReader bfr=new BufferedReader(new InputStreamReader(fis));
String content=bfr.readLine();//讀一行
String[] splits = content.split("##");
maps.put("name",splits[0]);
maps.put("pwd", splits[1]);
fis.close();
return maps;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
寫法6:SharedPreferences存取簡單數據★
十分簡單,工具類沒有了,就一個MainActivity.java
MainActivity.java
package com.example.login;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
import com.example.sp.R;
public class MainActivity extends Activity {
private EditText et_name;
private EditText et_pwd;
private CheckBox cb_check;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_name = (EditText) findViewById(R.id.et_username);
et_pwd = (EditText) findViewById(R.id.et_password);
cb_check = (CheckBox) findViewById(R.id.cb_ischeck);
//sp的xml中讀取出數據
SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE);
//讀直接取即可 不需要edit
String name=sp.getString("name","");
String pwd = sp.getString("pwd", "");
//直接展示 沒有默認值都設置爲空""了嘛
et_name.setText(name);
et_pwd.setText(pwd);
}
public void login(View v){
String username = et_name.getText().toString().trim();
String pwd = et_pwd.getText().toString().trim();
if(TextUtils.isEmpty(username)||TextUtils.isEmpty(pwd)){
Toast.makeText(this, "用戶名或密碼不能爲空!", 0).show();
}else{
System.out.println("連接服務器中...");
if(cb_check.isChecked()){
//getSharedPreferences(name, mode);
/**
* 文件以xml格式存儲
* name:xml文件名
* mode:模式 eg:MODE_PRIVATE(0) 私有的
*/
//獲取sp (創建xml)
SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE);
//獲取sp編輯器
Editor edit = sp.edit();
//利用編輯器往xml裏存值 (寫xml)
edit.putString("name", username);
edit.putString("pwd", pwd);
//一定記得提交 java沒法寫得像c#那麼好,跨平臺不能寫死
edit.commit();
Toast.makeText(this, "保存成功!", 0).show();
}else{
System.out.println("未保存密碼!");
}
}
}
}
改進:sp直接做一個成員變量
package com.example.login;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
import com.example.sp.R;
public class MainActivity extends Activity {
private EditText et_name;
private EditText et_pwd;
private CheckBox cb_check;
private SharedPreferences sp;// 獲取sp (創建xml)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//java不能寫死 設計上相比於C#就太醜了.....寫些機械冗餘的代碼
et_name = (EditText) findViewById(R.id.et_username);
et_pwd = (EditText) findViewById(R.id.et_password);
cb_check = (CheckBox) findViewById(R.id.cb_ischeck);
sp = getSharedPreferences("config", MODE_PRIVATE);
// 讀直接取即可 不需要edit
String name = sp.getString("name", "");
String pwd = sp.getString("pwd", "");
// 直接展示 沒有默認值都設置爲空""了嘛
et_name.setText(name);
et_pwd.setText(pwd);
}
public void login(View v) {
String username = et_name.getText().toString().trim();
String pwd = et_pwd.getText().toString().trim();
if (TextUtils.isEmpty(username) || TextUtils.isEmpty(pwd)) {
Toast.makeText(this, "用戶名或密碼不能爲空!", 0).show();
} else {
System.out.println("連接服務器中...");
if (cb_check.isChecked()) {
// 獲取sp編輯器
Editor edit = sp.edit();
// 利用編輯器往xml裏存值 (寫xml)
edit.putString("name", username);
edit.putString("pwd", pwd);
// 一定記得提交 java沒法寫得像c#那麼好,跨平臺不能寫死
edit.commit();
Toast.makeText(this, "保存成功!", 0).show();
} else {
System.out.println("未保存密碼!");
}
}
}
}
生成xml文件存儲數據
格式如下
改進2:記住cb_checked選中狀態
package com.example.login;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
import com.example.sp.R;
public class MainActivity extends Activity {
private EditText et_name;
private EditText et_pwd;
private CheckBox cb_check;
private SharedPreferences sp;// 獲取sp (創建xml)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//java不能寫死 設計上相比於C#就太醜了.....寫些機械冗餘的代碼
et_name = (EditText) findViewById(R.id.et_username);
et_pwd = (EditText) findViewById(R.id.et_password);
cb_check = (CheckBox) findViewById(R.id.cb_ischeck);
sp = getSharedPreferences("config", MODE_PRIVATE);
// 讀直接取即可 不需要edit
String name = sp.getString("name", "");
String pwd = sp.getString("pwd", "");
// 直接展示 沒有默認值都設置爲空""了嘛
et_name.setText(name);
et_pwd.setText(pwd);
//TODO 記憶選中狀態
cb_check.setChecked(sp.getBoolean("checked", false));
}
public void login(View v) {
String username = et_name.getText().toString().trim();
String pwd = et_pwd.getText().toString().trim();
if (TextUtils.isEmpty(username) || TextUtils.isEmpty(pwd)) {
Toast.makeText(this, "用戶名或密碼不能爲空!", 0).show();
} else {
System.out.println("連接服務器中...");
// 獲取sp編輯器
Editor edit = sp.edit();
if (cb_check.isChecked()) {
// 利用編輯器往xml裏存值 (寫xml)
edit.putString("name", username);
edit.putString("pwd", pwd);
edit.putBoolean("checked", true);
// 一定記得提交 java沒法寫得像c#那麼好,跨平臺不能寫死
edit.commit();
Toast.makeText(this, "保存成功!", 0).show();
} else {
edit.putBoolean("checked", false);
edit.commit();
Toast.makeText(this, "未保存密碼!", 0).show();
}
}
}
}
SharedPreferences很重要:
SharedPreferences詳細學習使用
xml序列化:自定義生成xml(備份短信到xml)
設計備份短信xml格式如下:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<smss>
<sms>
<address>110</address>
<body>你被捕了</body>
<date>2020</date>
</sms>
<sms>
<address>120</address>
<body>來醫院一趟</body>
<date>2019</date>
</sms>
</smss>
今天暫時取不出來,學到四大組件最後一個內容提供者(content provider)才行,今天只能模擬
小得1:
Android四大組件分別爲activity、service、content provider、broadcast receiver。
第七章不考那麼就考最簡單的兩大組件activity和content了,前3天正好講這些
小結1:
padding : 控件內容相對於控件邊框的距離
margin: 控件之間的距離