Download presentation
Presentation is loading. Please wait.
1
實驗十一:待辦事項程式 (儲存在手機上)
2
實驗十一 主題 目的 環境需求 本實驗為練習使用Android系統中操作SQLite 使用資料庫用來建立、新增、刪除、修改資料等功能
Java SE Development Kit (JDK) Android SDK Eclipse ADT 此實驗將使用Android系統中的資料庫,用來熟悉資料庫的操作。
3
實驗十一範例 將製作一個行程事項列表應用程式 按下新增後,會將輸入的資訊存入資料庫 列表處會顯示今天和今天之後的行程事項
此實驗將製作一個行程事項列表應用程式,行程事項需輸入日期、時間和標題,按下新增後,會將輸入的資訊存入資料庫,在上圖左的列表處,會顯示今天和今天之後的行程事項,點選列表中選項,會進入修改和刪除頁面,如上圖右,可進行資料修改和刪除。
4
範例使用的資料庫 資料庫名稱:schedule 資料表名稱:todolist 欄位名稱 資料型態 預設 備註 _id Integer
primary key Autoincrement 流水號 (系統自動新增) date Text 日期 time 時間 title 標題 範例中使用的資料庫檔案名稱為schedule,資料表名稱為todolist,具有4個欄位: _id、date、time、title,分別儲存流水號(系統自動新增)、日期、時間、標題。
5
res/layout/activity_main.xml <LinearLayout xmlns:android=" xmlns:tools=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_height="wrap_content" > <EditText android:layout_weight=“1” android:layout_height="wrap_content" android:hint=“輸入日期” android:inputType="date" /> android:layout_weight=“1” android:hint=“輸入時間” android:inputType="time" /> </LinearLayout> //接下頁 1 輸入日期和時間的編輯框 1. res/layout/activity_main.xml,將其佈局改為垂直線性佈局,在垂直線性佈局中拖入兩個水平線性佈局和一個ListView元件,在兩個水平線性佈局中,分別拖入兩個EditText和一個EditText與按鈕
6
res/layout/activity_main.xml <LinearLayout
android:layout_width="match_parent" android:layout_height="wrap_content" > <EditText android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="輸入標題" /> <Button android:text="新增" /> </LinearLayout> <ListView android:layout_height="wrap_content" /> 2 輸入標題的編輯框和新增的按鈕 2. res/layout/activity_main.xml,將其佈局改為垂直線性佈局,在垂直線性佈局中拖入兩個水平線性佈局和一個ListView元件,在兩個水平線性佈局中,分別拖入兩個EditText和一個EditText與按鈕
7
新增res/layout/list.xml 在layout按右鍵→新建→Android XML File XML名稱 3
8
res/layout/list.xml <?xml version="1.0" encoding="utf-8"?>
4 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" /> <TextView android:layout_width="wrap_content" </LinearLayout> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" android:layout_gravity="center_vertical" android:layout_weight="1" /> 4.一列列表選項佈局檔 一列列表選項佈局
9
新增DBAccess類別 套件名稱按右鍵→新建→類別 5 類別名稱 5.新增DBAccess類別,首先套件名稱按右鍵→新建→類別
10
src/DBAccess.java 繼承SQLiteOpenHelper 新增DBAccess建構子 DBAccess建構子 6 7
6.DBAccess類別繼承SQLiteOpenHelper,將滑鼠移到SQLiteOpenHelper,會跳出修正視窗,選擇匯入SQLiteOpenHelper(import android.database.sqlite.SQLiteOpenHelper;) 7.將滑鼠移到DBAccess,會跳出修正視窗,新增DBAccess類別的建構子
11
src/DBAccess.java 將滑鼠移到DBAccess 新增未實作方法 建立資料表 更新資料表 8
8.再將滑鼠移到DBAccess,會跳出修正視窗,選取新增未實作方法onCreate()和onUpgrade(),onCreate()方法中建立資料表,onUpgrade()方法用來更新資料表,在此方法中先將資料表刪除,再重新建立 更新資料表
12
src/DBAccess.java public class DBAccess extends SQLiteOpenHelper{
protected final static String TABLE_NAME="todolist";//定義資料表名稱 protected final static String ID_FIELD="_id";//定義_id欄位 protected final static String DATE_FIELD="date";//定義date欄位 protected final static String TIME_FIELD="time";//定義time欄位 protected final static String TITLE_FIELD="title";//定義title欄位 public DBAccess(Context context, String name, CursorFactory factory,int version) { super(context, name, factory, version); } 9 建立資料表的SQL語法 10 @Override public void onCreate(SQLiteDatabase db) { String sql="create table "+TABLE_NAME+"(" +ID_FIELD+" integer primary key autoincrement," +DATE_FIELD+" text, " +TIME_FIELD+" text, " +TITLE_FIELD+" text)"; db.execSQL(sql); } 9.建立資料表名稱、_id欄位、date欄位、time欄位和title欄位的變數 10.在onCreate()方法中建立資料表並執行建立資料表的SQL語法 執行SQL語法
13
src/DBAccess.java 若建立此DBAccess物件時,傳入的版本與應用程式中存在的資料庫版本不同時,會執行此方法
11 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("drop table if exists "+TABLE_NAME); onCreate(db); } 將資料表刪除 重新建立資料表 自訂新增資料方法,傳入參數為:日期、時間、標題 12 long add(String date, String time, String title) { SQLiteDatabase db=this.getWritableDatabase();//取得讀寫資料表物件 ContentValues values =new ContentValues(); values.put(DATE_FIELD, date); values.put(TIME_FIELD, time); values.put(TITLE_FIELD, title); long result=db.insert(TABLE_NAME, null, values);//執行新增資料 db.close(); return result;//回傳新資料的row ID,若為-1表示新增失敗 } 11. onUpgrade()方法若建立此DBAccess物件時,傳入的版本與應用程式中存在的資料庫版本不同時,會執行此方法,將舊的資料表刪除再重新建立新的資料表 12. long add(String date, String time, String title)為自訂新增資料方法,傳入參數為:日期、時間、標題
14
src/DBAccess.java 自訂修改資料方法,傳入參數為:日期、時間、標題、更新條件,無須修改則傳入null
13 long update(String date, String time, String title,String whereClause) { SQLiteDatabase db=this.getWritableDatabase();//取得讀寫資料表物件 ContentValues values =new ContentValues(); if(date!=null) values.put(DATE_FIELD, date); if(time!=null) values.put(TIME_FIELD, time); if(title!=null) values.put(TITLE_FIELD, title); //執行更新資料 long result=db.update(TABLE_NAME, values, whereClause, null); db.close(); return result;//回傳更新資料筆數 } 14 自訂刪除資料方法,傳入參數為:欲刪除資料的_id欄位值 13. long update(String date, String time, String title,String whereClause)為自訂修改資料方法,傳入參數為:日期、時間、標題、更新條件,無須修改則傳入null,將滑鼠移到ContentValues,跳出修正視窗,選取匯入ContentValues(import android.content.ContentValues;) 14. int delete(String _id)為自訂刪除資料方法,傳入參數為:欲刪除資料的_id欄位值 int delete(String _id){ SQLiteDatabase db=this.getWritableDatabase();//取得讀寫資料表物件 int result=db.delete(TABLE_NAME, ID_FIELD+" ="+_id, null); //進行刪除 db.close(); return result;//回傳刪除筆數 }
15
src/DBAccess.java 自訂查詢資料方法,傳入參數為:查詢條件、排序欄位
15 自訂查詢資料方法,傳入參數為:查詢條件、排序欄位 Cursor getData(String whereClause, String orderBy){ SQLiteDatabase db=this.getReadableDatabase();//取得讀寫資料表物件 Cursor c=db.query(TABLE_NAME, new String[]{ID_FIELD,DATE_FIELD,TIME_FIELD,TITLE_FIELD}, whereClause, null, null, null, orderBy); //進行查詢 return c; } 15. Cursor getData(String whereClause, String orderBy)為自訂查詢資料方法,傳入參數為:查詢條件、排序欄位,將滑鼠移到Cursor,跳出修正視窗,匯入Cursor(import android.database.Cursor;)
16
src/MainActivity.java public class MainActivity extends Activity {
DBAccess access; ListView lv; SimpleCursorAdapter adapter=null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv=(ListView)findViewById(R.id.listView1); Button btn=(Button)findViewById(R.id.button1); btn.setOnClickListener(this); lv.setOnItemClickListener(this); access=new DBAccess(this, "schedule", null, 1); } 16 cursor資料指標物件與ListView連接的adapter,cursor中必須要有_id欄位資料 產生自訂DBAccess物件,以建立資料庫、 表和進行資料表操作 資料庫檔案名稱為schedule,版本為1 17 16.建立全域變數,cursor資料指標物件與ListView連接的adapter,cursor中必須要有_id欄位資料 17. findViewById()找到視窗上的ListView和Button,監聽Button按紐,將滑鼠移到setOnClickLinstener,跳出修正視窗,選取讓MainActivity實作tOnClickLinstener,監聽ListView,將滑鼠移到setOnItemClickListener,跳出修正視窗,選取讓MainActivity實作OnItemClickListener。 access=new DBAccess(this, “schedule”, null, 1)產生自訂DBAccess物件,以建立資料庫、表和進行資料表操作,資料庫檔案名稱為schedule,版本為1
17
src/MainActivity.java 18 將滑鼠移到MainActivity,選取新增未實作方法
18.將滑鼠移到MainActivity,跳出修正視窗,選取新增未實作方法,實作onItemClick()和onClick()
18
src/MainActivity.java 當列表資料點選時會執行此方法,arg3為此筆資料的_id值 @Override
19 當列表資料點選時會執行此方法,arg3為此筆資料的_id值 @Override public void onItemClick(AdapterView<?> arg0, View arg1,int arg2,long arg3) { Intent intent=new Intent(); intent.setClass(this, modify.class); //設定新活動視窗類別 Bundle bdl=new Bundle(); bdl.putString("id", arg3+"");//將arg3傳遞到新的活動視窗中 intent.putExtras(bdl); startActivity(intent); //開啟新的活動視窗 } 19. 當列表資料點選時會執行onItemClick()方法,arg3為此筆資料的_id值,將選取到的資料_id值綁在Bundle傳遞給modify活動視窗
19
src/MainActivity.java 找出輸入日期、時間、標題的文字框物件和取得輸入的文字 @Override
public void onClick(View v) { EditText ed=(EditText)findViewById(R.id.editText1); String date=ed.getText()+""; ed=(EditText)findViewById(R.id.editText2); String time=ed.getText()+""; ed=(EditText)findViewById(R.id.editText3); String title=ed.getText()+""; long result=access.add(date, time, title);//執行新增資料操作 if(result>=0) {//新增成功 Toast.makeText(this, "新增成功", Toast.LENGTH_LONG).show(); Cursor c=access.getData( DBAccess.DATE_FIELD+">= strftime('%Y-%m-%d','now')", DBAccess.DATE_FIELD+" ,"+DBAccess.TIME_FIELD); adapter.changeCursor(c);//更新ListView呈現的資料 }else//失敗 Toast.makeText(this, "新增資料失敗", Toast.LENGTH_LONG).show(); } 找出輸入日期、時間、標題的文字框物件和取得輸入的文字 20 20.當點選新增按鈕會執行OnClick()方法,找出輸入日期、時間、標題的文字框物件和取得輸入的文字,使用DBAccess類別
20
src/MainActivity.java @Override protected void onResume() {
Cursor c=access.getData( DBAccess.DATE_FIELD+">= strftime('%Y-%m-%d','now')", DBAccess.DATE_FIELD+" ,"+DBAccess.TIME_FIELD); if(adapter==null){ //表示第一次執行,需建立SimpleCursorAdapter物件 adapter=new SimpleCursorAdapter(this, R.layout.list,c, new String[]{DBAccess.DATE_FIELD, DBAccess.TIME_FIELD, DBAccess.TITLE_FIELD}, new int[]{R.id.textView1,R.id.textView2,R.id.textView3}, 0); lv.setAdapter(adapter); }else adapter.changeCursor(c);//更新ListView呈現的資料 super.onResume(); } 21 21. onResume()方法中,會去查詢todolist資料表中大於等於今天日期的資料,並將回傳的資料指標物件與ListView元件透過SimpleCursorAdapter進行繫結,要使用SimpleCursorAdapter需注意的是此方法需傳入Cursor物件,此Cursor物件必需要有_id資料欄位的資料,否則將產生執行錯誤。取得資料表中大於等於今天日期(strftime('%Y-%m-%d','now')方法是 SQLite內建的語法,now表示取得現在日期時間,strftime表示將日期進行格式化,%Y表示顯示四位數年分,%m表示顯示兩位數月份、%d表示顯示兩位數日期,詳細資料可參考SQLite官網),並依據日期時間遞增排序。
21
新增modify活動視窗 套件名稱按右鍵→新建→其他 22
22.新增modify活動視窗,在套件名稱按右鍵→新建→其他,新建Android Activity
22
新增modify活動視窗 23 活動視窗名稱 23.新增一個活動視窗,活動視窗名稱為modify
23
res/layout/activity_modify.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="日期" /> <EditText android:layout_weight="1" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="date" /> </LinearLayout> <TextView android:text="時間" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <EditText android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:inputType="time" /> //接下頁 24 修改日期和時間的編輯框 24.修改res/layout/activity_modify.xml,在將其佈局改為垂直線性佈局,在垂直線性佈局中拖入兩個水平線性佈局,第一個水平線性佈局放入兩個TextView和EditText
24
res/layout/activity_modify.xml 25 <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="標題" /> <EditText android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="修改" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="刪除" /> 25.第二個水平線性佈局放入一個TextView和EditText以及兩個Button 修改標題的編輯框 修改和刪除的按鈕
25
src/modify.java public class modify extends Activity {
DBAccess access; EditText dateET; EditText timeET; EditText titleET; String id; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_modify); Button btn=(Button)findViewById(R.id.button1); btn.setOnClickListener(this); btn=(Button)findViewById(R.id.button2); access=new DBAccess(this, "schedule", null, 1); Bundle bdl=getIntent().getExtras(); id=bdl.getString("id","0"); //接下頁 } 26 27 26.建立全域變數,包含DBAccess和EditText以及存放主視窗傳遞過來的_id 27.用findViewById()找出視窗上的按鈕,將Bundle中的_id欄位取出 將Bundle中的_id欄位取出
26
src/modify.java @Override
public void onCreate(Bundle savedInstanceState) { Cursor c=access.getData(DBAccess.ID_FIELD+" ="+id, null); c.moveToFirst(); dateET=(EditText)findViewById(R.id.editText1); dateET.setText(c.getString(1)); timeET=(EditText)findViewById(R.id.editText2); timeET.setText(c.getString(2)); titleET=(EditText)findViewById(R.id.editText3); titleET.setText(c.getString(3)); } 27 c.getString(1), c.getString(2), c.getString(3)分別取出Cursor物件中第二個(date), 第三個(time), 第四個(title)欄位值 27.呼叫DBAccess類別的getData方法進行資料查詢條件為_id等於上一個活動視窗傳遞過來的資料,使用findViewById()找到視窗上的元件,getString()取得欄位資料,c.getString(1), c.getString(2), c.getString(3)分別取出Cursor物件中第二個(date), 第三個(time), 第四個(title)欄位值
27
src/modify.java 28 28.監聽按紐,將滑鼠移到setOnClickListener,跳出修正視窗,選擇讓modify實作OnClickListener,接著將滑鼠移到modify,選取新增未實作方法。
28
src/modify.java @Override public void onClick(View v) {
switch (v.getId()) { case R.id.button1://資料表中的資料修改 access.update(dateET.getText()+"", timeET.getText()+"", titleET.getText()+"",DBAccess.ID_FIELD+" ="+id); break; case R.id.button2://資料表中的資料刪除 access.delete(id); } finish();//關閉修改刪除活動視窗 29 29.監聽按紐,如果為按下修改按鈕則呼叫DBAccess類別的update()方法修改資料庫的資料,如果為按下刪除按鈕,則呼叫DBAccess類別的delete()方法刪除資料庫的資料
29
資料庫儲存的位置 DDMS選擇模擬器→data→data→此專案的套件名稱→database
Similar presentations