day05_數據存儲

1.按鈕四種點擊事件寫法

  [1]通過內部類來實現按鈕點擊事件
  [2]通過匿名內部類去實現
btn_test1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"我被點擊了",Toast.LENGTH_LONG).show();
}
});
 [3]當頁面上有多個按鈕 讓當前類實現OnClickListener.通過switch語句 通過id 來判斷具體點擊的是哪個按鈕
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
 
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//1.找的按鈕
Button btn_test1 = (Button) findViewById(R.id.button1);
Button btn_test2 = (Button) findViewById(R.id.button2);
Button btn_test3 = (Button) findViewById(R.id.button3);
Button btn_test4 = (Button) findViewById(R.id.button4);
 
/* //2.通過查看 api文檔得知 可以通過匿名內部類去實現
btn_test1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"我被點擊了",Toast.LENGTH_LONG).show();
}
});*/
//3 當頁面上有多個按鈕需要點擊的時候 可以這樣寫
btn_test1.setOnClickListener(this);
btn_test2.setOnClickListener(this);
btn_test3.setOnClickListener(this);
btn_test4.setOnClickListener(this);
 
 
}
 
@Override
public void onClick(View v) {
//4.由於每個按鈕的id 不一樣 所以可以通過id來判斷用戶到底點擊的是哪個按鈕
switch (v.getId()){
case R.id.button1:
Toast.makeText(MainActivity.this,"我被點擊了111",Toast.LENGTH_LONG).show();
break;
case R.id.button2:
Toast.makeText(MainActivity.this,"我被點擊了222",Toast.LENGTH_LONG).show();
break;
case R.id.button3:
Toast.makeText(MainActivity.this,"我被點擊了333",Toast.LENGTH_LONG).show();
break;
 
case R.id.button4:
Toast.makeText(MainActivity.this,"我被點擊了444",Toast.LENGTH_LONG).show();
break;
}
}
}
[4]按鈕第四種點擊事件寫法
    [4.1]在按鈕上聲明一個onClick屬性
<Button
android:text="test5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="16dp"
android:onClick="click"
android:id="@+id/button5" />
    [4.2]在mainActivity寫一個方法 要求方法名和屬性名一樣 並且接收一個參數 參數類型View.
public void click(View v){
Toast.makeText(MainActivity.this,"我被點擊了555",Toast.LENGTH_LONG).show();
}
   按鈕繼承的是view類,看view的原碼,Ctrl+f 搜 onclick,原理就是我們前面講的反射,通過屬性名,反射“click”方法
   反射用的是(不知道爲什麼我的看不到原碼)
   所以click方法必須是public的。
   實際開發中:使用匿名內部類或者第四種寫法

2.android中常見佈局

   [1]線性佈局   水平  垂直.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"//設置朝向,這個是垂直,另一個是水平
android:layout_height="match_parent">
<!--@符合就代表R文件-->
<TextView
android:id="@+id/tv_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="請輸入手機號:"
android:textSize="25sp"
/>
 
<EditText
android:id="@+id/et_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="請輸入手機號"//輸入前的輸入提示
/>
 
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="撥打此號碼"
/>
 
</LinearLayout>
   [2]相對佈局  裏面的控件默認都從左上角開始排列
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
 
<!--快速格式化代碼 ctrl + alt + l-->
 
<!--@符合就代表R文件-->
<TextView
android:id="@+id/tv_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="請輸入手機號:"
android:textSize="25sp" />
 
 
<EditText
android:id="@+id/et_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/tv_number"
android:hint="請輸入手機號"1
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/et_number"//_above代表處在誰上面。_torightof右面;_toleftof左面
android:text="撥打此號碼"
 
/>
 
</RelativeLayout>
   [3]幀佈局   分層展示控件,特點就是疊在一起(兩個控件都是match_parent的情況下)不會出現覆蓋,而是分層展示
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--@符合就代表R文件-->
<TextView
android:id="@+id/tv_number"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="這是視頻播放的內容:"
android:textSize="25sp"
/>
 
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="撥打"
android:layout_gravity="center"//相對於父親居中; center_vertical 水平居中
                    //還有一個 android:gravity="center" 這個相對於控件本身居中
/>
 
</FrameLayout>
[4]表格佈局  表格由行和列構成 
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
 
<!--一個tablerow就代表一行 具體的控件表示列-->
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content">
>
 
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="1111" />
 
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="2222" />
</TableRow>
 
 
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content">
>
 
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="1111" />
 
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="2222" />
</TableRow>
 
</TableLayout>
[5]絕對佈局 已經過時 我們開發中很少用 
    AbsoluteLayout  設置寬高layout_height/width,位置layou_x/y = "12dp"
[6]總結:實際開發中我們使用線性佈局和相對佈局組合.

3.android中單位

          
   
         px  給控件或者佈局設置一個具體的寬和高.(這個不建議使用,因爲會固定大小)

http://blog.csdn.net/jiangwei0910410003/article/details/40509571
px   :是屏幕的像素點
dp   :一個基於density的抽象單位,如果一個160dpi的屏幕,1dp=1px
dip  :等同於dp
sp   :同dp相似,但還會根據用戶的字體大小偏好來縮放(建議使用sp作爲文本的單位,其它用dip)


4.android中單元測試

   
   1.根據是否知道源代碼 黑盒(不知道源碼)  白盒(需要知道源代碼)  
   2.根據測試粒度  方法 單元(和方法測試一個意思) 系統(ee比較多)  集成 (安卓,比如美團的客戶端和服務端要集成到一起,測試一下)
   3.根據測試的暴力程度  壓力(12306,就是同時訪問人數)  冒煙(一直把設備測到冒煙爲止)  谷歌提供了一個工具(monkey) cmd--adb shell--monkey--monkey 1000

   
然後直接點旁邊的
public class ExampleUnitTest {
 
 
@Test
public void testAdd(){
Calc calc = new Calc();
int add = calc.add(3, 5);
 
//判斷一下結果是真的還是假的 斷言: 參數1:期望值 參數2:實際值
assertEquals(8,add);
 
}
 
}

5.Log類的使用

  
System.out.println("aab");
//android開發中 谷歌單獨提供了打印日誌的類 Log 參數1:對log信息的標示 參2:就代表具體打印的日誌信息
Log.e("MainActivity","e級別");
Log.w("MainActivity","w級別");
Log.d("MainActivity","d級別");
Log.i("MainActivity","i級別");
Log.v("MainActivity","v級別");
1.android.util.Log常用的方法有以下5個:Log.v() Log.d() Log.i() Log.w() 以及 Log.e() 。根據首字母對應VERBOSE,DEBUG,INFO, WARN,ERROR。
2、Log.v 的調試顏色爲黑色的,任何消息都會輸出,這裏的v代表verbose囉嗦的意思,平時使用就是Log.v(“”,”“);
3、Log.d的輸出顏色是藍色的,僅輸出debug調試的意思,但他會輸出上層的信息,過濾起來可以通過DDMS的Logcat標籤來選擇.
4、Log.i的輸出爲綠色,一般提示性的消息information,它不會輸出Log.v和Log.d的信息,但會顯示i、w和e的信息
5、Log.w的意思爲橙色,可以看作爲warning警告,一般需要我們注意優化Android代碼,同時選擇它後還會輸出Log.e的信息。
6、Log.e爲紅色,可以想到error錯誤,這裏僅顯示紅色的錯誤信息,這些錯誤就需要我們認真的分析,查看棧的信息了。
7.注意:不同的打印方法在使用時都是某個方法帶上(String tag, String msg)參數,tag表示的是打印信息的標籤,msg表示的是需要打印的信息,例如。

6.登錄案例

   
    代碼實現[1]:畫ui
<?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_main"
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.itheima.login.MainActivity">
 
<EditText
android:id="@+id/et_name"
android:layout_width="match_parent"
android:layout_height="wrap_content" 後面加的:android:inputType="textPassword"// 代表輸入格式爲文字,不可見
android:hint="請輸入用戶名"
/>
<EditText
android:id="@+id/et_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="請輸入密碼"
/>
 
<RelativeLayout
android:layout_width="match_parent"
android:layout_marginTop="20dp"
android:layout_height="wrap_content">
<CheckBox
android:id="@+id/cb_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="記住用戶名密碼"
/>
 
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="登錄"
android:layout_alignParentRight="true"//表示靠近父親的右邊
android:onClick="click"
/>
 
 
</RelativeLayout>
 
 
</LinearLayout>
  [2]根據ui寫對應的業務邏輯 
     [2.1]登錄流程如下:
   
      [2.2]把用戶名和密碼保存起來  由於保存數據和讀取數據業務邏輯是獨立的所以單獨寫到一個工具類裏
public class UserUtils {
//用來存儲用戶密碼業務方法 ctrl + alt + t 抓異常
public static boolean save(String name, String pwd) {
 
try {
//1.爲了存儲方便 拼接字符串
String data = name + "##"+pwd;
//2.把data存到手機裏(不能存到 C ,D盤) ---->手機裏有內部存儲目錄() 和 外部存儲目錄
File file = new File("/data/data/com.itheima.login/info.txt");
//3.創建一個文件輸入流
FileOutputStream fos = new FileOutputStream(file);
//4.把data寫到文件
fos.write(data.getBytes());
//5.關流
fos.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
 
 
}
 
 
//讀取info.txt文件裏面的內容
public static Map<String,String> readInfo(){
 
try {
//1.創建一個map對象用來存儲 我們讀取出來的數據
Map<String,String> maps = new HashMap<>();
//2.去info.txt文件裏面讀
File file = new File("/data/data/com.itheima.login/info.txt");
//3.創建FileinputStream
FileInputStream fis = new FileInputStream(file);
//4.使用一個轉換流 可以快速讀取一行數據
BufferedReader bufr = new BufferedReader(new InputStreamReader(fis));
//5.讀一行 把結果數據讀取出來
String result = bufr.readLine(); // aa##123
//6.切割字符串 根據##
String[] split = result.split("##");
//7.獲取用戶名 aa
String name = split[0];
//8.獲取密碼
String pwd = split[1];
//9.把name 和 pwd存到集合裏
maps.put("name",name);
maps.put("pwd",pwd);
return maps;
} catch (Exception e) {
e.printStackTrace();
return null;
}
 
 
}
 
 
 
}
    [2.3]當保存數據就調用save方法 當讀取數據就調用readinfo方法


7.Context類(上下文)

    

                                                                                燈壞了 ----->工具箱找板子 ---修燈
                                                                                寶馬x6 -----> 工具箱找對應工具                                              
   
     
                        上下文就是谷歌給我們提供的一個工具類。上下文中的方法很多,都可以直接調用。

8.把數據存儲到sd卡

   [8.1]會獲取sd卡路徑
String sdPath = Environment.getExternalStorageDirectory().getPath();
   [8.2]判斷sd卡狀態是否可用
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){ }
   [8.3]如何判斷sd卡空間是否夠用
//1.獲取sd卡空間
File file = Environment.getExternalStorageDirectory();
//2.在file類中提供了2個方法 可以獲取總空間 和 可用空間 谷歌已經幫助我們封裝了
long totalSpace = file.getTotalSpace();
long usableSpace = file.getUsableSpace();
//3.所以需要把值轉換爲對應的單位 參數1:上下文this, //TODO 明天講
String totalSpaceSize = Formatter.formatFileSize(this, totalSpace);
String usableSpaceSize = Formatter.formatFileSize(this, usableSpace);
 
System.out.println("total:"+totalSpaceSize);
System.out.println("usable:"+usableSpaceSize);
 建議使用 adb 指令 

9.文件權限

   
  
10.SharedPreferences偏愛 喜愛
  
  
//3.說明用戶名密碼不爲空 使用sp來存數據 獲取sp的實例
SharedPreferences sp = getSharedPreferences("config", 0); //:使用sp 系統會生成一個xml格式的文件
//3.1 獲取sp的編輯器
SharedPreferences.Editor edit = sp.edit();
//3.2 存數據 用戶名 和密碼
edit.putString("name",name);
edit.putString("pwd",pwd);
//3.3 調用commit方法提交數據
edit.commit();

11.今天總結
 1.按鈕四種點擊事件寫法 ☆☆  
 2.android五大布局  ☆ 
 3.android 單位  dp sp ☆ 
 4.android單元測試   ☆    asserteaquals 斷言
 5.monkey 2000 
 6.Log類 ☆ 
 7.登錄案例  ☆ 
 8.Context   ☆   //類名.this  this區別 
 9.把數據存儲到sd卡 
 10.文件權限 
 11.sp存儲數據 ☆  adb指令☆ 
 
    

1.撥打電話

1.畫xml
2.新建類,繼承AppCompatActivity ,覆蓋方法,獲取佈局路徑
public class MainActivity extends AppCompatActivity {
 
private List<Sms> lists;
 
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout);//這裏是獲取

3.查看api,找到按鈕的用法。獲取方法
Button btn_test1 = (Button) findViewById(R.id.button2);
4.監聽按鈕
btn_test1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"我被點擊了",Toast.LENGTH_LONG).show();
}
});
5.再監聽裏面寫打電話的邏輯,用Intent類,是studio裏面定義好工具。
    獲取號碼:                    String number = et_number.getText().toString().trim();
    新建Intent類:                Intent intent = new Intent();
    調用intent打電話動作: intent.setAction(Intent.ACTION_CALL);
    傳入數據:                    intent.setData(Uri.parse("tel:"+number));
    開啓動作:                    startActivity(intent);
6.開啓權限:谷歌工程師的代理權限,誰寫誰負責,反正意思就是和谷歌無關。(下面代碼加到main文件夾裏面的AndroidManifest.xml的聲明下面,大概第三行)
<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>

2.新建模擬器要開這個,開了以後再重新啓動模擬器


2.登錄案例(步驟看老師筆記,下面是詳細代碼)

1.先寫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_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.itheima.login.MainActivity">
 
<EditText
android:id="@+id/et_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="請輸入用戶名" />
 
<EditText
android:id="@+id/et_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:hint="請輸入密碼" />
 
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp">
 
<CheckBox
android:id="@+id/cb_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="記住用戶名密碼" />
 
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:onClick="click"
android:text="登錄" />
 
</RelativeLayout>
 
</LinearLayout>

2,主類
package com.itheima.login;
 
 
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;
 
import java.util.Map;
 
/**
* Author: 邱瓏
* Version: 1.0
* Date: 2017/8/21
* Modify:
* Description: //TODO
* Copyright notice:
*/
public class Test extends AppCompatActivity {
 
 
private TextView tx1;
private TextView tx2;
private CheckBox cb;
 
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout);
 
tx1 = (TextView) findViewById(R.id.textView1);
tx2 = (TextView) findViewById(R.id.textView2);
cb = (CheckBox) findViewById(R.id.checkBox);
 
Map<String,String> map = UserUtils.read();
if(map.equals(null)){
 
}else{
tx1.setText(map.get("name"));
tx2.setText(map.get("pwd"));
}
 
 
 
 
}
public void click(View view){
String name = tx1.getText().toString().trim();
String pwd = tx2.getText().toString().trim();
if(TextUtils.isEmpty(name)||TextUtils.isEmpty(pwd)){
Toast.makeText(this,"用戶名或密碼不能爲空",Toast.LENGTH_LONG).show();
}
else if(cb.isChecked()){
boolean a = UserUtils.save(this,name,pwd);
if(a){
Toast.makeText(this,"成功",Toast.LENGTH_LONG).show();
}else
Toast.makeText(this,"失敗",Toast.LENGTH_LONG).show();
 
}else{
Toast.makeText(this,"沒有勾選保存信息",Toast.LENGTH_LONG).show();
}
 
}
}

3.UserUtils類
package com.itheima.login;
 
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.util.HashMap;
import java.util.Map;
 
/**
* Created by jinxi on 2017/8/20.
*/
public class UserUtils {
public static boolean save(String name, String pwd) {
String num = name+"##"+pwd;
File f = new File("data/data/com.itheima.login/info.txt");
try {
FileOutputStream fos = new FileOutputStream(f);
fos.write(num.getBytes());
fos.close();
return true;
 
} catch (Exception e) {
e.printStackTrace();
return false;
}
 
}
public static Map<String,String> read(){
Map<String,String> map = new HashMap();
File f = new File("data/data/com.itheima.login/info.txt");
try {
FileInputStream fis = new FileInputStream(f);
BufferedReader br = new BufferedReader(new FileReader(f));
String a =br.readLine();
String[] as =a.split("##");
map.put("name",as[0]);
map.put("pwd",as[1]);
return map;
} catch (Exception e) {
e.printStackTrace();
return null;
}
 
}
 
 
}

4.優化代碼:使用context代替寫死的地址輸入
    這裏需要在把UserUtils類中save方法和read方法添加一個參數
    save(String name, String pwd)----->save( Context context,String name, String pwd)
String path = context.getFilesDir().getPath();
File f = new File(path,"info21.txt");//後面是給文件命名
//File f = new File("data/data/com.itheima.login/info.txt");
再次改進,直接用context裏面的方法,後面也要改,這裏省略了
// String savePath = context.getFilesDir().getPath(); // data/data/當前應用包名/files/
// File file = new File(savePath,"info2.txt");
// FileOutputStream fos = new FileOutputStream()
//3.創建一個文件輸入流 mode參數: 0:代表私有的模式
FileOutputStream fos = context.openFileOutput("info3.txt", 0); //info3.txt // data/data/當前應用包名/files/


先改老師筆記,有多餘時間,在通過修改的筆記寫自己的理解

 1.按鈕四種點擊事件寫法 ☆☆  
 2.android五大布局  ☆ 
 3.android 單位  dp sp ☆ 
 4.android單元測試   ☆    asserteaquals 斷言
 5.monkey 2000 
 6.Log類 ☆ 
 7.登錄案例  ☆ 
 8.Context   ☆   //類名.this  this區別 
 9.把數據存儲到sd卡 
 10.文件權限 
 11.sp存儲數據 ☆  adb指令☆ 
 



   

   
  
   
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章