Professional Documents
Culture Documents
Trong bi tp ny, bn s construct mt notes list n gin cho php user thm mi cc notes nhng khng c edit chng. Trong bi ny, chng ta s lm hiu cc phn c bn sau: C bn v ListActivity, to v x l menu options. S dng SQLite database lu tr cc notes. Bind d liu t mt database cursor vo mt ListView s dng mt SimpleCursorAdapter. C bn v screen layout (layout mt list view), thm cc item vo activity menu, v cch thc activity x l cc selection cho menu. Trc khi bt u, bn vo y download bi tp c cha NotepadCodeLab.
I.Step 1
B1.Trong Eclipse, click vo File->New->Android Project. B2.Chn Create project from existing source. B3.Click Browse v navigate n ni c cha th mc NotepadCodeLab v chn Notepadv1. B4.Click Finish.
II.Step 2
Sau khi to project Notepadv1, bn s thy lp NotesDbAdapter lp ny c cung cp ng gi d liu truy cp vo SQLite database m s nm gi cc notes data v cho php bn cp nht n. pha trn ca lp l mt s nh ngha constant s c s dng trong ng dng tm kim d liu t cc tn trng thch hp trong database. Tn ca database l data v tn ca table l notes gm c 3 field: _id, title v body. Constructor ca NotesDbAdapter c cha mt Context, cho php n giao tip vi cc kha cnh ca OS Android. Lp Activity implement lp Context, v vy bn thng s s dng t kha this t Activity, khi cn mt Context. Phng thc open() gi mt th hin ca lp DatabaseHelper (lp ny c ci t cc b trong lp NotesDbAdapter v kt tha t SQLiteOpenHelper). N gi getWritableDatabase() x l vic to v m database cho bn. Phng thc createNote() c cha cc string cho title v body ca mt note mi, sau to note trong database. Gi s note mi c to ra thnh cng, phng thc ny cng tr v gi tr _id cho note mi c to ra.
Phng thc deleteNote() c cha mt rowId cho mt note c th, v xa note t database. Phng thc fetchAllNote() thc hin truy vn v tr v mt Cursor cho tt c cc note trong database, l n gi phng thc query(). Trong phng thc query(), tham s u tin l tn ca database table truy vn (trong v d ny, DATABASE_TABLE l notes), tham s tip theo l danh sch cc column m bn mun tr v, trong v d ny l cc column: _id, title, v body, v vy chng c xc nh l mt mng String. Cc tham s thip theo ln lt l: selection, selectionArgs, groupBy, having v orderBy; gi tr ca having bng null, c ngha l bn mun tt c data, khng cn group chng v c th t mc nh. Xem thm SQLiteDatabase. Lu : Mt Cursor c tr v ch khng phi l mt collection ca cc row. iu ny cho php Android s dng cc resource mt cch hiu qu - thay v put cc d liu trc tip vo b nh, con tr s retrieve v release d liu khi cn thit, iu ny hiu qu hn nhiu vic s dng cc table c cha nhiu row. Phng thc fetchNote() tng t nh fetchAllNote() nhng ch nhn mt note vi rowId. Cui cng, phng thc updateNote() c cha rowId, title v body, v s dng mt th hin ca ContentValues cp nht note ca rowId cho trc.
III.Step 3
M file notepad_list.xml trong th mc res/layout, di y l mt s iu bn nn bit v file layout ny: Tt c cc file layout trong Android u bt u vi dng XML header:
<?xml version="1.0" encoding="utf-8"?>
Dng tip theo thng l mt nh ngha layout, trong v d ny l LinearLayout. Namespace XML ca Android lun lun c nh ngha ti top level ca component hay layout trong XML cc tags android: c th c s dng thng qua phn cn li ca file.
xmlns:android="http://schemas.android.com/apk/res/android"
IV.Step 4
By gi, bn cn to ra layout nm gi list. Thm on m sau vo bn trong phn t LinearLayout nh sau:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content">
<ListView android:id="@android:id/list" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@android:id/empty" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/no_notes"/> </LinearLayout>
Biu tng @ trong id strings ca cc tag ListView v TextView c ngha l XML parser nn parse v expand phn cn li ca id string v s dng mt ID resource. ListView v TextView c th c xem nh l hai view khc nhau, ch mt trong s s c hin th ti mt thi im. ListView s c s dng khi c cc notes c hin th, trong khi TextView (trong c mt gi tr mc nh l "No Notes Yet!" c nh ngha nh l mt string resource trong res/values/strings.xml) s c hin th nu khng c bt k note no hin th. Cc ID list v empty c cung cp cho bn bng Android platform, v vy, chng ta phi prefix id vi android: (v d, @android:id/list). View vi id empty c s dng t ng khi ListAdapter khng c d liu cho ListView. Ngoi ra, bn c th thay view empty mc nh bng cch s dng setEmptyView(View) trn ListView. Ni rng ra, lp android.R l mt tp hp cc resource c nh ngha trc cung cp cho bn bi platform, trong khi lp R ca project ca bn l tp hp cc resource project ca bn c nh ngha. Cc resource c trong lp resource android.R c th c s dng trong cc file XML bng cch s dng prefix name space android: (nh chng ta thy y).
V.Step 5
to ra danh sch cc notes trong ListView, bn cn nh ngha mt View cho mt row: B1.To mt layout resource mi notes_row.xml trong th mc res/layout. B2.Thm cc ni dung sau y file va to:
<?xml version="1.0" encoding="utf-8"?> <TextView android:id="@+id/text1" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
Trong trng hp ny, bn to ra mt id mi gi l text1. Du + sau @ trong id string cho bit rng id nn c to ra t ng nh l mt resource nu n khng tn ti, v vy chng ta nh ngha n s dng. B3.Lu file. M lp R.java trong project ca bn, bn s thy cc nh ngha mi cho notes_row v text1, c ngha l by gi chng ta c th truy cp vo chng trong code.
VI.Step 6
Tip theo, m lp Notepadv1. Trong bc ny, bn s sa i n tr thnh mt list adapter v hin th cc notes, ng thi cho php thm note mi. Notepadv1 k tha t mt lp con ca Activity, l ListActivity, trong c chc nng b sung cho ph hp vi loi cng vic m bn c th mun lm vic trn mt list, v d: hin th cc list item trong cc row ln mn hnh, di chuyn qua li gia cc list item, v cho php la chn trn chng. Trong lp ny, c mt bin mNoteNumber c s dng to ra cc note title c nh s (numbered). ng thi, chng c 3 phng thc s c override sau y: o onCreate() c gi khi activity c start, n c s dng thit lp (set up) cc resource v state cho activity khi n ang chy. o onCreateOptionsMenu() c s dng populate menu cho Activity. Menu s c hin th khi user nhn phm MENU trn thit b, n c mt danh sch cc option user c th chn. o onOptionsItemSelected() c s dng x l cc s kin pht sinh khi user chn mt item trong Menu.
VII.Step 7
Thay i lp Notepadv1 k tha ListActivity thay v Activity.
public class Notepadv1 extends ListActivity {
Lu : Bn s phi import ListActivity vo Notepadv1 s dng Eclipse, nhn t hp phm ctrl-shift-O trn Windows hay Linux, hay cmd-shift-O trn Mac.
VIII.Step 8
Ci t phng thc onCreate(). y bn s ci t title cho Activity (hin th top ca mn hnh), s dng layout notepad_list m bn to ra trc , thit lp mt th hin ca NotesDbAdapter truy cp d liu note, v populate danh sch vi cc note title sn c: B1.Trong phng thc onCreate(), gi super.onCreate() vi tham s saveInstanceState. B2.Gi setContentView() v gn R.layout.notepad_list.
B3.Ti top ca lp, to mt bin lp private mi mDbHelper ca lp NotesDbAdapter. B4.Tr li phng thc onCreate(), to ra mt i tng mi NotesDbAdapter v gn n cho trng mDbHelper. B5.Gi phng thc open() trn mDbHelper m (hay to mi) database. B6.Cui cng, to mi mt phng thc fillData() nhn d liu v populate ListView s dng helper chng ta vn cha nh ngha phng thc ny.
IX.Step 9
Ci t phng thc onCreateOptionsMenu(). By gi, bn s to button Add item c truy cp bng cch nhn menu button trn thit b. V chng ta xc nh rng n chim v tr u tin trong Menu. B1.Trong resource strings.xml (trong th mc res/values), v thm mt string mi c t tn menu_insert vi gi tr ca n l Add Item.
<string name="menu_insert">Add Item</string>
B3.Trong phng thc onCreateOptionsMenu(), khai bo mt bin cc b result kiu boolean v gn cho super.onCreateOptionsMenu(). B4.Sau , thm menu item vi phng thc add(). By gi phng thc onCreateOptionsMenu() trng nh sau:
Cc i s c gn vo trong phng thc add() cho bit: mt group identifier, mt unique ID, th t ca item v resource ca string s dng cho item.
X.Step 10
Ci t phng thc onOptionsItemSelected(). Trong phn ny, chng ta s x l menu item Add Note. Khi item ny trn Menu c chn, phng thc onOptionsItemSelected() s c gi vi item.getId() thit lp cho INSERT_ID (hng m bn s dng identify menu item). B1.Gi super.onOptionsItemSelected() vo cui phng thc ny. B2.Vit mt biu thc switch da vo item.getId(). Phng thc onOptionsItemSelected() trng nh sau:
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case INSERT_ID: createNote(); return true; } } return super.onOptionsItemSelected(item);
XI.Step 11
Ci t phng thc createNote(). Trong phng thc ny, bn n gin ch to mt note mi vi title c gn da trn mt counter (v d, Note 1, Note 2) vi mt body trng. B1.Xy dng name vi Note v counter c nh ngha trong lp ny:
String noteName = "Note " + mNoteNumber++;
B2.Gi mDbHelper.createNote() s dng noteName lm title v lm body . B3.Gi phng thc fillData() populate danh sch cc notes phng thc ny s c to trong bc tip theo. o Phng thc createNote() trng nh sau:
private void createNote() { String noteName = "Note " + mNoteNumber++; mDbHelper.createNote(noteName, "");
fillData();
XII.Step 12
nh ngha v ci t phng thc fillData(). Phng thc ny s dng SimpleCursorAdapter v mt Cursor bind n vo cc field c cung cp trong layout. Cc field ny nh ngha cc phn t row ca list (trong v d ny, field text1 trong layout notes_row.xml). lm iu ny bn phi cung cp mt mapping t field title trong Cursor tr v n text1, m c thc hin bng cch nh ngha hai mng: u tin l mt mng string vi danh sch cc column cho map (trong v d ny l "title", t constant NotesDbAdapter.KEY_TITLE) v, th hai l mt mng int c cha cc tham chiu n cc view bn bind d liu vo (R.id.text1).
private void fillData() { // Get all of the notes from the database and create the item list Cursor c = mDbHelper.fetchAllNotes(); startManagingCursor(c); String[] from = new String[] { NotesDbAdapter.KEY_TITLE }; int[] to = new int[] { R.id.text1 }; // Now create an array adapter and set it to display using our row SimpleCursorAdapter notes = new SimpleCursorAdapter(this, R.layout.notes_row, c, from, to); setListAdapter(notes); }
Sau y l nhng g m chng ta thc hin: B1.Sau khi nhn c Cursor t mDbHelper.fetchAllNotes(), chng ta s dng phng thc startManagingCursor() ca Activity cho php Android quan tm n lifecycle ca Cursor thay v chng ta lo lng v iu (chng ta s tho lun vn ny trong bi tp 3, nhng by gi ch bit rng iu ny cho php Android lm mt s cng vic qun l resource cho bn). B2.Sau chng ta to ra mt mng string, trong khai bo cc column m chng ta mun (trong v d ny, ch c title), v mt mng int nh ngha cc View m chng ta mun bind cc column. B3.Bc tip theo l khi to SimpleCursorAdapter. Ging nh nhiu lp trong Android, SimpleCursorAdapter cn mt Context thc hin cc cng vic ca n, v vy chng ta gn this cho context (cc lp con ca Activity thc thi Context). Chng ta gn View notes_row to ra trc lm ch cha (receptable) cho d liu, Cursor m chng ta va to ra v cc mng. Trong tng lai, hy nh rng vic mapping t cc column v cc resource c thc hin bng cch s dng th t ca hai mng mt cch tng ng. Nu bn c nhiu column bind, v nhiu View bind chng vo, bn s xc nh chng theo th t, v
d bn c th s dng {NotesDbAdapter.KEY_TITLE, NotesDbAdapter.KEY_BODY} v {R.id.text1, R. id.text2} bind hai field vo row (v cng cn phi nh ngha text2 trong notes_row.xml, cho body text). y l cch m bn c th bind cc field vo mt row n (v c c mt custom row layout).
XIII.Step 13
Chy ng dng.
Notepad Exercise 2
Trong bi tp ny, bn s thm mt Activity th hai vo ng dng notepad, cho php user to v chnh sa cc notes. Bn cng s cho php user xa cc notes ang tn ti thng qua mt context menu. Activity mi ny chu trch nhim to cc notes mi bng cch collect user input v ng gi n vo mt Bundle tr v c cung cp bi Intent. Bi tp ny th hin: Xy dng mt Activity mi v thm n vo Android manifest. Gi mt Activity khc khng ng b (asynchronously) s dng startActivityForResult(). Gn d liu vo cc Activity thng qua cc i tng Bundle. Nng cao v s dng screen layout. To mt context menu.
I.Step 1
To project mi s dng source t Notepadv2 trong th mc NotepadCodeLab nh bn lm trong bi tp 1. M project Notepadv2 v xem xt mt s vn sau: M file string.xml trong th mc res/values c mt vi string mi m bn s s dng cho cc chc nng mi. M lp Notepadv2, bn s thy mt s constant mi c nh ngha cng vi mt field mi mNotesCursor nm gi cursor. Trong phng thc fillData() c mt vi comment mi v s dng field mi mNotesCursor lu tr Cursor. Phng thc onCreate() vn nh bi tp 1. C mt s phng thc cn override mi: onCreateContextMenu(), onContextItemSelected(), onListItemClick() v onActivityResult().
II.Step 2
u tin, to menu context cho php user xa cc notes. M lp Notepadv2 v thc hin cc cng vic sau: B1.Vo cui phng thc onCreate(), ng k context menu cho mi item trong ListView bng cch gi registerForContextMenu() v gn n vo ListView.
registerForContextMenu(getListView());
Bi v activity ca bn k tha t ListActivity, nn getListView() s tr v mt i tng local ListView cho activity. Lc ny, mi item trong ListView ny s kch hot context menu.
III.Step 3
By gi, bn ng k ListView cho mt context menu v nh ngha item trong n, v cng vic cn lm l x l khi mt item c chn. lm iu ny, bn cn xc nh list ID ca item c chn, sau xa n. V vy, bn x l trong phng thc onContextItemSelected() nh sau:
@Override public boolean onContextItemSelected(MenuItem item) { switch(item.getItemId()) { case DELETE_ID: AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); mDbHelper.deleteNote(info.id); fillData(); return true; } return super.onContextItemSelected(item); }
y, bn nhn mt AdapterContextMenuInfo t getMenuInfo(). Trng id ca i tng ny n cho bn bit v tr ca item trong ListView. Sau , bn gn gi tr ny vo deleteNote() ca NotesDbAdapter v note s c xa.
IV.Step 4
Trong phng thc createNote(), to mt i tng Intent to mt note (ACTIVITY_CREATE) s dng lp NoteEdit. Sau , pht sinh Intent s dng phng thc startActivityForResult().
startActivityForResult(i, ACTIVITY_CREATE);
Phng thc startActivityForResult() c s dng pht sinh mt Intent gi n mt Activity mi (trong v d ny l NoteEdit), v sau khi Activity mi ny hon tt, th activity gi phng thc ny s nhn c mt callback onActivityResult() v bn s ci t phng thc ny trong bc sau. C mt cch khc gi mt Activity l s dng startActivity(), tuy nhin khi gi phng thc ny, activity ca bn s khng nhn c callback onActivityResult() sau khi activity mi kt thc. Trong cc bc sau, chng ta s to ra lp EditNote.
V.Step 5
Trong bc ny, bn s ci t callback onListItemClick(), callback ny c gi khi user chn mt item trong list. Phng thc ny c 4 tham s ln lt l: mt ListView, mt View bn trong ListView khi c chn, position trong list c chn, v mRowId ca item c chn. Phng thc ny s dng mt Intent edit note s dng lp NoteEdit, sau thm d liu vo extras Bundle ca Intent (chng s c gn vo Activity c gi). i tng Intent ny c s dng gn title, body v mRowId cho note ang c edit. Cui cng gi phng thc startActivityForResult().
@Override protected void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); Cursor c = mNotesCursor; c.moveToPosition(position); Intent i = new Intent(this, NoteEdit.class); i.putExtra(NotesDbAdapter.KEY_ROWID, id); i.putExtra(NotesDbAdapter.KEY_TITLE, c.getString( c.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE))); i.putExtra(NotesDbAdapter.KEY_BODY, c.getString( c.getColumnIndexOrThrow(NotesDbAdapter.KEY_BODY))); startActivityForResult(i, ACTIVITY_EDIT); }
Phng thc putExtra() c s dng thm cc item vo extras Bundle. Trong v d ny, bn s dng Bundle gn title, body v mRowId ca note mun edit. Lu : Khi bn gn field mNotesCursor cho mt bin cc b, iu ny c thc hin nh l mt ti u ha ca m Android. Truy cp vo mt bin cc b hiu qu hn so vi truy cp vo mt field trong Dalvik VM.
VI.Step 6
Override callback onActivityResult(), callback ny c pht sinh khi mt Activity tr v mt result v Activity launch trc s dng startActivityForResult(). Phng thc ny c 3 tham s: requestCode: c xc nh trong Intent invocation (trong v d ny hoc ACTIVITY_CREATE hoc ACTIVITY_EDIT). resultCode: m kt qu hay m li ca li gi, zero nu mi th OK v non-zero nu fail. intent: y l Intent c to bi Activity ang tr v result. N c s dng tr v d liu trong Intent extras.
@Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); Bundle extras = intent.getExtras(); switch (requestCode) { case ACTIVITY_CREATE: String title = extras.getString(NotesDbAdapter.KEY_TITLE); String body = extras.getString(NotesDbAdapter.KEY_BODY); mDbHelper.createNote(title, body); fillData(); break; case ACTIVITY_EDIT: Long mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID); if (mRowId != null) { String editTitle = extras.getString(NotesDbAdapter.KEY_TITLE); String editBody = extras.getString(NotesDbAdapter.KEY_BODY); mDbHelper.updateNote(mRowId, editTitle, editBody); } fillData(); break; } }
VII.Step 7
M file note_edit.xml, trong file ny bn lu thuc tnh android:layout_weight. Tt c cc View u c layout_weight bng zero. N cho bit t trng ca space sn c ca cc widget nn c s dng. V d, c 2 widget, widget u tin thit lp thuc tnh android:weight =1, v widget th hai thit lp android:weight=2 th nu cn space trong container cha 2 widget ny, widget th hai s chim gp i space sn c so vi widget th nht.
VIII.Step 8
To lp NoteEdit k tha t Activity. Override phng thc onCreate().
package com.android.demo.notepad2; import android.app.Activity; import android.os.Bundle; public class NoteEdit extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } }
IX.Step 9
Trong bc ny, bn s ci t phng thc onCreate() ca NoteEdit. B1.Thit lp layout.
setContentView(R.layout.note_edit);
B4.Ti top ca lp, khai bo mt field private Long mRowId lu tr mRowId ang c edit.
B5.Tip tc trong onCreate(), khi to title, body v mRowId t extras Bundle trong Intent.
mRowId = null; Bundle extras = getIntent().getExtras(); if (extras != null) { String title = extras.getString(NotesDbAdapter.KEY_TITLE); String body = extras.getString(NotesDbAdapter.KEY_BODY); mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID); if (title != null) { mTitleText.setText(title); } if (body != null) { mBodyText.setText(body); } }
X.Step 10
Trong phn ny, bn s ci t phng thc onClick() cho confirmButton. B1.To i tng Bundle v put title v body vo n.
Bundle bundle = new Bundle(); bundle.putString(NotesDbAdapter.KEY_TITLE, mTitleText.getText().toString()); bundle.putString(NotesDbAdapter.KEY_BODY, mBodyText.getText().toString()); if (mRowId != null) { bundle.putLong(NotesDbAdapter.KEY_ROWID, mRowId); }
Trong v d ny, Intent n gin l data carrier c cha Bundle (vi title, body v mRowId). Phng thc setResult() c s dng thit lp result code v Intent tr v c gn tr li cho Intent caller. Trong v d ny, mi th lm vic OK, v vy bn tr v RESULT_OK cho result code. Phng thc finish() c s dng kt thc Activity hin ti.
confirmButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { Bundle bundle = new Bundle(); bundle.putString(NotesDbAdapter.KEY_TITLE, mTitleText.getText() .toString()); bundle.putString(NotesDbAdapter.KEY_BODY, mBodyText.getText() .toString()); if (mRowId != null) { bundle.putLong(NotesDbAdapter.KEY_ROWID, mRowId); }
} }); }
XI.Step 11
Trong bc ny, bn m file AndroidManifest.xml thm activity mi (NoteEdit) trong tag <application> nh sau:
<activity android:name=".NoteEdit" />
XII.Step 12
Chy ng dng.
Notepad Exercise 3
Trong bi tp ny, bn s s dng cc callback life-cycle lu tr v nhn state data ca ng dng. Bi tp ny s m t: Life-cycle events v lm th no ng dng ca bn c th s dng chng. Cc k thut duy tr trng thi ca ng dng.
I.Step 1
Import ng dng Notepadv3 vo Eclipse. ng dng hin ti c mt s vn nhn nt BACK trn thit b s gy ra mt crash, v bt c iu g xy ra trong qu trnh chnh sa s lm cho qu trnh edit b mt. fix vn ny, chng ta chuyn hu ht cc chc nng nh to v chnh sa note vo lp NoteEdit, v gii thiu mt full life cycle cho cc note ang c chnh sa.
B1.Remove code trong lp NoteEdit m parse title v body t extras Bundle. Thay vo , s dng lp DBHelper truy cp vo cc notes t database mt cch trc tip. Bn cn gn vo activity NoteEdit mt mRowId nu edit, ngc li nu create th khng gn g. Bn remove cc dng code sau y:
String title = extras.getString(NotesDbAdapter.KEY_TITLE); String body = extras.getString(NotesDbAdapter.KEY_BODY);
B2.Bn s thit lp gi tr cho title v body trong UI, nn bn cng b cc dng code sau y:
if (title != null) { mTitleText.setText(title); } if (body != null) { mBodyText.setText(body); }
II.Step 2
Trong lp NoteEdit, to mt field NotesDbAdapter nh sau:
private NotesDbAdapter mDbHelper;
III.Step 3
Trong NoteEdit, bn cn kim tra savedInstanceState cho mRowId, trong trng hp note editing c cha mt saved state trong Bundle, m bn s recover (iu ny xy ra nu Activity mt focus v sau restart).
c thay th bng:
mRowId = (savedInstanceState == null) ? null : (Long) savedInstanceState .getSerializable(NotesDbAdapter.KEY_ROWID); if (mRowId == null) { Bundle extras = getIntent().getExtras(); mRowId = extras != null ? extras.getLong(NotesDbAdapter.KEY_ROWID): null; }
B2.Bn cn kim tra null cho savedInstanceState, bi bn cn load mRowId t extras Bundle nu n khng c cung cp bi savedInstanceState. B3.Lu vic s dng cc Bundle.getSerializable() thay v Bundle.getLong(). on code phn sau tr v mt long primitive v do khng th c s dng i din cho trng hp khi mRowId l null.
IV.Step 4
Tip theo, bn cn populate cc field da trn mRowId nu bn c n:
populateFields();
Phng thc ny c t trc confirmButton.setOnClickListener(). Bn s nh ngha phng thc ny trong phn tip theo.
V.Step 5
Loi b Bundle trong onClick(). Activity khng cn tr v bt k thng tin extras n caller. V bi v khng cn c mt Intent tr v, chng ta ch s dng setResult() nh sau:
Bn cn cn thn trong vic lu tr cc cp nht hay cc notes mi trong database, s dng cc phng thc life-cycle. Tm li, phng thc onCreate() s trng nh sau:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mDbHelper = new NotesDbAdapter(this); mDbHelper.open(); setContentView(R.layout.note_edit); setTitle(R.string.edit_note); mTitleText = (EditText) findViewById(R.id.title); mBodyText = (EditText) findViewById(R.id.body); Button confirmButton = (Button) findViewById(R.id.confirm); mRowId = (savedInstanceState == null) ? null : (Long) savedInstanceState .getSerializable(NotesDbAdapter.KEY_ROWID ); if (mRowId == null) { Bundle extras = getIntent().getExtras(); mRowId = extras != null ? extras.getLong(NotesDbAdapter.KEY_ROWID) : null; } this.populateFields(); confirmButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { setResult(RESULT_OK); finish(); } }); }
VI.Step 6
nh ngha phng thc populateFields().
private void populateFields() { if (mRowId != null) { Cursor note = mDbHelper.fetchNote(mRowId); startManagingCursor(note); mTitleText.setText(note.getString(note .getColumnIndexOrThrow(NotesDbAdapter.KEY _TITLE))); mBodyText.setText(note.getString(note .getColumnIndexOrThrow(NotesDbAdapter.KEY _BODY))); } }
Phng thc ny s dng NotesDbAdapter.fetchNote() nhm tm kim mt note hp l edit, sau n gi startManagingCursor() t lp Activity, l mt phng thc tin li m Android cung cp qun l life-cycle ca Cursor. iu ny s release v re-create cc resource tng t nh life-cycle ca Activity. Sau , bn ch cn ly cc gi tri title v body t Cursor v populate cc phn t View vi chng.
VII.Step 7
Vn trong lp NoteEdit, bn override cc phng thc sau: onSaveInstanceState() onPause() v onResume(). y l cc phng thc life-cycle (cng vi onCreate() m bn thc hin trn). onSaveInstanceState() c gi bi Android nu Activity ang c stop v c th b kill trc khi n c tr v! iu ny c ngha l n s lu tr cc trng thi cn thit ti khi to vi cng mt iu kin khi Activity c restart. Trong thc t, i tng savedInstanceState trong onCreate() cng chnh l i tng outState trong phng thc onSaveInstanceState(). onPause() lun lun c gi khi Activity kt thc, ngay c khi chng ta gi tng minh phng thc finish(). S dng n lu tr note hin ti vo database. Ngoi ra, bn c th gii phng cc ti nguyn no c th c trong phng thc ny. onResume() s gi populateFields() c cc notes t database v populate cc field.
B1.Override onSaveInstanceState()
@Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); saveState(); outState.putSerializable(NotesDbAdapter.KEY_ROWID, mRowId);
B2.Override onPause()
@Override protected void onPause() { super.onPause(); saveState(); }
B3.Override onResume()
@Override protected void onResume() { super.onResume(); populateFields(); }
Lu : saveState() phi c gi trong c onSaveInstanceState() v onPause() m bo rng d liu c lu vo database. Bi v khng c iu g m bo rng phng thc onSaveInstanceState() s lun lun c gi, v khi c gi th n s gi trc onPause().
VIII.Step 8
nh ngha saveState() put d liu vo database.
private void saveState() { String title = mTitleText.getText().toString(); String body = mBodyText.getText().toString(); if (mRowId == null) { long id = mDbHelper.createNote(title, body); if (id > 0) { mRowId = id; } } else { mDbHelper.updateNote(mRowId, title, body); }
Lu rng chng ta capture gi tr tr v t createNote() v nu mt row ID hp l c tr v, chng ta lu n trong field mRowId c th cp nht note trong tng lai, hn l to ra mt ci mi.
IX.Step 9
Ci t li phng thc onActivityResult() trong lp Notepadv3. Tt c cc cng vic cp nht by gi u xy ra trong NoteEdit life cycle, v vy trong onActivityResult(), bn ch cn cp nht li d liu ca ListView.
@Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); fillData(); }
X.Step 10
Trong onListItemClick(), bn b cc dng code sau y:
Cursor c = mNotesCursor; c.moveToPosition(position); i.putExtra(NotesDbAdapter.KEY_TITLE, c.getString( c.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE))); i.putExtra(NotesDbAdapter.KEY_BODY, c.getString( c.getColumnIndexOrThrow(NotesDbAdapter.KEY_BODY)));
@Override protected void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); Intent i = new Intent(this, NoteEdit.class); i.putExtra(NotesDbAdapter.KEY_ROWID, id); startActivityForResult(i, ACTIVITY_EDIT); }
By gi, bn c th remove field mNotesCursor, v trong phng thc fillData() s dng mt bin cc b notesCursor thay th cho mNotesCursor.