「Android Notepad チュートリアル」の版間の差分
ナビゲーションに移動
検索に移動
1行目: | 1行目: | ||
− | ==Android Notepad チュートリアル== | + | ==[[Android Notepad チュートリアル]]== |
[[Android]] | [[Java]] | [[Eclipse]] | | [[Android]] | [[Java]] | [[Eclipse]] | | ||
9行目: | 9行目: | ||
==(1) 簡単なノートリストの作成== | ==(1) 簡単なノートリストの作成== | ||
*新しいノートを追加する(まだ編集はできない) | *新しいノートを追加する(まだ編集はできない) | ||
− | * | + | *ListActi[[vi]]ty を使ってみる |
− | * | + | *[[SQL]]iteを使ってみる |
===プロジェクトの作成=== | ===プロジェクトの作成=== | ||
20行目: | 20行目: | ||
===NotesDbAdapter=== | ===NotesDbAdapter=== | ||
====用途==== | ====用途==== | ||
− | * | + | *NotesDbAdapterは[[SQL]]iteへのデータアクセスをカプセル化する。 |
====宣言==== | ====宣言==== | ||
*クラスの先頭で、テーブルのフィールドおよびデータベースが存在しない場合に生成する文字列を定義 | *クラスの先頭で、テーブルのフィールドおよびデータベースが存在しない場合に生成する文字列を定義 | ||
*データベースは data という名前で、notes という _id、title、bodyの3つのフィールドをもつテーブルを一つ持つ。 | *データベースは data という名前で、notes という _id、title、bodyの3つのフィールドをもつテーブルを一つ持つ。 | ||
====コンストラクタ==== | ====コンストラクタ==== | ||
− | *コンストラクタは、Context パラメータを取り、それにより Android OS との通信を許可。これは Android にアクセスする一般的な方法 | + | *コンストラクタは、Context パラメータを取り、それにより [[Android]] OS との通信を許可。これは [[Android]] にアクセスする一般的な方法 |
− | * | + | *Acti[[vi]]ty クラスは Context を実装しているため、Contextが必要な時に渡すことができる。 |
====メソッド==== | ====メソッド==== | ||
=====open()===== | =====open()===== | ||
− | *open() | + | *open()メソッドは、[[Database]]Helper のインスタンスを呼び出す。 |
− | * | + | *[[Database]]Helper は SQLiteOpenHelper のローカル実装。 |
− | * | + | *getWritable[[Database]]() で、データベースを作成、オープン |
=====close() ===== | =====close() ===== | ||
46行目: | 46行目: | ||
=====fetchAllNotes()===== | =====fetchAllNotes()===== | ||
*クエリーを発行して、カーソルを得る | *クエリーを発行して、カーソルを得る | ||
− | *query() には、データベーステーブル名、取得したいカラムリスト、残りのフィールドは順に、selection、selectionArgs、 groupBy、 | + | *query() には、データベーステーブル名、取得したいカラムリスト、残りのフィールドは順に、selection、selectionArgs、 groupBy、 ha[[vi]]ng、orderBy |
*fetchNote()は、fetchAllNotes() と同様だが、行IDで1つの note を取得する | *fetchNote()は、fetchAllNotes() と同様だが、行IDで1つの note を取得する | ||
55行目: | 55行目: | ||
====LinearLayout の設定==== | ====LinearLayout の設定==== | ||
− | =====すべての Android のXMLレイアウトのヘッダーは以下で始まらなければいけない===== | + | =====すべての [[Android]] のXMLレイアウトのヘッダーは以下で始まらなければいけない===== |
<?xml version="1.0" encoding="utf-8"?>. | <?xml version="1.0" encoding="utf-8"?>. | ||
=====次に、たいていの場合、以下の様なレイアウトを置く===== | =====次に、たいていの場合、以下の様なレイアウトを置く===== | ||
LinearLayout | LinearLayout | ||
− | =====トップレベルのコンポーネントまたはレイアウトで Android のネームスペースを宣言する===== | + | =====トップレベルのコンポーネントまたはレイアウトで [[Android]] のネームスペースを宣言する===== |
xmlns:android="http://schemas.android.com/apk/res/android" | xmlns:android="http://schemas.android.com/apk/res/android" | ||
===LinearLayout === | ===LinearLayout === | ||
86行目: | 86行目: | ||
====オーバーライドメソッド==== | ====オーバーライドメソッド==== | ||
=====onCreate() ===== | =====onCreate() ===== | ||
− | * | + | *Acti[[vi]]tyが開始されたときに呼び出される。 |
*リソースの設定、ステートの設定を実施 | *リソースの設定、ステートの設定を実施 | ||
− | ===== | + | =====onCreateOptions[[Menu]]() ===== |
− | * | + | *Acti[[vi]]ty メニューの有効化 |
*ユーザーがメニューボタンをたたいた時に呼び出される | *ユーザーがメニューボタンをたたいた時に呼び出される | ||
=====onOptionsItemSelected() ===== | =====onOptionsItemSelected() ===== | ||
95行目: | 95行目: | ||
*メニューから生成されるイベントを制御 | *メニューから生成されるイベントを制御 | ||
====基底クラスの変更==== | ====基底クラスの変更==== | ||
− | * | + | *Acti[[vi]]ty を ListActi[[vi]]ty に |
− | public class Notepadv1 extends | + | public class Notepadv1 extends ListActi[[vi]]ty |
====onCreate()==== | ====onCreate()==== | ||
− | private NotesDbAdapter | + | private NotesDbAdapter mDb[[Help]]er; |
− | /** Called when the | + | /** Called when the acti[[vi]]ty is first created. */ |
@Override | @Override | ||
public void onCreate(Bundle savedInstanceState) { | public void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | super.onCreate(savedInstanceState); | ||
− | setContentView(R.layout.notepad_list); | + | setContentView([[R]].layout.notepad_list); |
− | + | mDb[[Help]]er = new NotesDbAdapter(this); | |
− | + | mDb[[Help]]er.open(); | |
fillData(); | fillData(); | ||
} | } | ||
*fillData() はまだ未作成 | *fillData() はまだ未作成 | ||
− | ==== | + | ====onCreateOptions[[Menu]]()==== |
<?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||
<resources> | <resources> | ||
121行目: | 121行目: | ||
− | public class Notepadv1 extends | + | public class Notepadv1 extends ListActi[[vi]]ty { |
− | public static final int INSERT_ID = Menu.FIRST; | + | public static final int INSERT_ID = [[Menu]].FIRST; |
: | : | ||
@Override | @Override | ||
− | public boolean | + | public boolean onCreateOptions[[Menu]]([[Menu]] menu) { |
// TODO Auto-generated method stub | // TODO Auto-generated method stub | ||
− | boolean result = super. | + | boolean result = super.onCreateOptions[[Menu]](menu); |
− | menu.add(0, | + | menu.add(0, INSE[[R]]T_ID, 0, [[R]].string.menu_insert); |
return result; | return result; | ||
} | } | ||
135行目: | 135行目: | ||
====onOptionsItemSelected()==== | ====onOptionsItemSelected()==== | ||
@Override | @Override | ||
− | public boolean onOptionsItemSelected( | + | public boolean onOptionsItemSelected([[Menu]]Item item) { |
// TODO Auto-generated method stub | // TODO Auto-generated method stub | ||
switch (item.getItemId()) { | switch (item.getItemId()) { | ||
− | case | + | case INSE[[R]]T_ID: |
createNote(); | createNote(); | ||
return true; | return true; | ||
148行目: | 148行目: | ||
public void createNote() { | public void createNote() { | ||
String noteName = "Note " + mNoteNumber++; | String noteName = "Note " + mNoteNumber++; | ||
− | + | mDb[[Help]]er.createNote(noteName, ""); | |
fillData(); | fillData(); | ||
} | } | ||
====fillData()==== | ====fillData()==== | ||
private void fillData() { | private void fillData() { | ||
− | Cursor c = | + | Cursor c = mDb[[Help]]er.fetchAllNotes(); |
startManagingCursor(c); | startManagingCursor(c); | ||
160行目: | 160行目: | ||
SimpleCursorAdapter notes = | SimpleCursorAdapter notes = | ||
− | new SimpleCursorAdapter(this, R.layout.notes_row, c, from, to); | + | new SimpleCursorAdapter(this, [[R]].layout.notes_row, c, from, to); |
setListAdapter(notes); | setListAdapter(notes); | ||
} | } | ||
166行目: | 166行目: | ||
===ここまでで、起動=== | ===ここまでで、起動=== | ||
[[File:0147_android_notepad02.jpg]] | [[File:0147_android_notepad02.jpg]] | ||
− | ==(2) | + | ==(2) Acti[[vi]]ty の追加、高度なレイアウトの使用など== |
*http://developer.android.com/resources/tutorials/notepad/notepad-ex2.html | *http://developer.android.com/resources/tutorials/notepad/notepad-ex2.html | ||
− | * | + | *2つめのActi[[vi]]tyを作成しマニフェストに追加 |
− | * | + | *startActi[[vi]]tyForResult()を使って非同期で別のActi[[vi]]tyを呼び出す |
− | *Bundle オブジェクトで | + | *Bundle オブジェクトで Acti[[vi]]ty 間でデータを受け渡す |
*他のさらに高度なレイアウトの使用 | *他のさらに高度なレイアウトの使用 | ||
*コンテキストメニューの作成 | *コンテキストメニューの作成 | ||
179行目: | 179行目: | ||
*fillData()では、mNotesCursor カーソルフィールドを使うようになっている。 | *fillData()では、mNotesCursor カーソルフィールドを使うようになっている。 | ||
*onCreate()は変更なし。 | *onCreate()は変更なし。 | ||
− | *いくつかのオーバーライドメソッドが記述されている( | + | *いくつかのオーバーライドメソッドが記述されている(onCreateContext[[Menu]](), onContextItemSelected(), onListItemClick() and onActivityResult()) |
===表示されている note を削除するためのコンテキストメニューを追加する=== | ===表示されている note を削除するためのコンテキストメニューを追加する=== | ||
− | ==== | + | ====registerForContext[[Menu]]()==== |
− | *ListView | + | *ListView のアイテムそれぞれに順にコンテキストメニューにregisterForContext[[Menu]]()を呼び出して登録 |
*onCreate() の最後に以下を追加 | *onCreate() の最後に以下を追加 | ||
@Override | @Override | ||
public void onCreate(Bundle savedInstanceState) { | public void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | super.onCreate(savedInstanceState); | ||
− | setContentView(R.layout.notes_list); | + | setContentView([[R]].layout.notes_list); |
− | + | mDb[[Help]]er = new NotesDbAdapter(this); | |
− | + | mDb[[Help]]er.open(); | |
fillData(); | fillData(); | ||
− | + | registerForContext[[Menu]](getListView()); | |
} | } | ||
− | ==== | + | ====onCreateContext[[Menu]]()==== |
@Override | @Override | ||
− | public void | + | public void onCreateContext[[Menu]](Context[[Menu]] menu, View v, |
− | + | Context[[Menu]]Info menuInfo) { | |
− | super. | + | super.onCreateContext[[Menu]](menu, v, menuInfo); |
// TODO: fill in rest of method | // TODO: fill in rest of method | ||
− | super. | + | super.onCreateContext[[Menu]](menu, v, menuInfo); |
− | menu.add(0, DELETE_ID, 0, R.string.menu_delete); | + | menu.add(0, DELETE_ID, 0, [[R]].string.menu_delete); |
} | } | ||
====onContextItemSelected()==== | ====onContextItemSelected()==== | ||
@Override | @Override | ||
− | public boolean onContextItemSelected( | + | public boolean onContextItemSelected([[Menu]]Item item) { |
// TODO: fill in rest of method | // TODO: fill in rest of method | ||
switch(item.getItemId()) { | switch(item.getItemId()) { | ||
case DELETE_ID: | case DELETE_ID: | ||
− | + | AdapterContext[[Menu]]Info info = (AdapterContext[[Menu]]Info) item.get[[Menu]]Info(); | |
− | + | mDb[[Help]]er.deleteNote(info.id); | |
fillData(); | fillData(); | ||
return true; | return true; | ||
222行目: | 222行目: | ||
} | } | ||
− | ==== | + | ====onActi[[vi]]tyResult()==== |
@Override | @Override | ||
− | protected void | + | protected void onActi[[vi]]tyResult(int requestCode, int resultCode, Intent intent) { |
// TODO Auto-generated method stub | // TODO Auto-generated method stub | ||
− | super. | + | super.onActi[[vi]]tyResult(requestCode, resultCode, intent); |
Bundle extras = intent.getExtras(); | Bundle extras = intent.getExtras(); | ||
switch(requestCode) { | switch(requestCode) { | ||
− | case | + | case ACTIVITY_C[[R]]EATE: |
String title = extras.getString(NotesDbAdapter.KEY_TITLE); | String title = extras.getString(NotesDbAdapter.KEY_TITLE); | ||
String body = extras.getString(NotesDbAdapter.KEY_BODY); | String body = extras.getString(NotesDbAdapter.KEY_BODY); | ||
− | + | mDb[[Help]]er.createNote(title, body); | |
fillData(); | fillData(); | ||
break; | break; | ||
case ACTIVITY_EDIT: | case ACTIVITY_EDIT: | ||
− | Long | + | Long m[[R]]owId = extras.getLong(NotesDbAdapter.KEY_[[R]]OWID); |
− | if ( | + | if (m[[R]]owId != null) { |
String editTitle = extras.getString(NotesDbAdapter.KEY_TITLE); | String editTitle = extras.getString(NotesDbAdapter.KEY_TITLE); | ||
String editBody = extras.getString(NotesDbAdapter.KEY_BODY); | String editBody = extras.getString(NotesDbAdapter.KEY_BODY); | ||
− | + | mDb[[Help]]er.updateNote(mRowId, editTitle, editBody); | |
} | } | ||
fillData(); | fillData(); | ||
251行目: | 251行目: | ||
// TODO: fill in implementation | // TODO: fill in implementation | ||
Intent i = new Intent(this, NoteEdit.class); | Intent i = new Intent(this, NoteEdit.class); | ||
− | + | startActi[[vi]]tyForResult(i, ACTIVITY_CREATE); | |
} | } | ||
264行目: | 264行目: | ||
c.moveToPosition(position); | c.moveToPosition(position); | ||
Intent i = new Intent(this, NoteEdit.class); | Intent i = new Intent(this, NoteEdit.class); | ||
− | i.putExtra(NotesDbAdapter. | + | i.putExtra(NotesDbAdapter.KEY_[[R]]OWID, id); |
i.putExtra(NotesDbAdapter.KEY_TITLE, | i.putExtra(NotesDbAdapter.KEY_TITLE, | ||
c.getString(c.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE))); | c.getString(c.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE))); | ||
270行目: | 270行目: | ||
c.getString(c.getColumnIndexOrThrow(NotesDbAdapter.KEY_BODY))); | c.getString(c.getColumnIndexOrThrow(NotesDbAdapter.KEY_BODY))); | ||
− | + | startActi[[vi]]tyForResult(i, ACTIVITY_EDIT); | |
} | } | ||
− | ==== | + | ====onActi[[vi]]tyResult()==== |
@Override | @Override | ||
− | protected void | + | protected void onActi[[vi]]tyResult(int requestCode, int resultCode, Intent intent) { |
− | super. | + | super.onActi[[vi]]tyResult(requestCode, resultCode, intent); |
// TODO: fill in rest of method | // TODO: fill in rest of method | ||
282行目: | 282行目: | ||
switch(requestCode) { | switch(requestCode) { | ||
− | case | + | case ACTIVITY_C[[R]]EATE: |
String title = extras.getString(NotesDbAdapter.KEY_TITLE); | String title = extras.getString(NotesDbAdapter.KEY_TITLE); | ||
String body = extras.getString(NotesDbAdapter.KEY_BODY); | String body = extras.getString(NotesDbAdapter.KEY_BODY); | ||
− | + | mDb[[Help]]er.createNote(title, body); | |
fillData(); | fillData(); | ||
break; | break; | ||
case ACTIVITY_EDIT: | case ACTIVITY_EDIT: | ||
− | Long | + | Long m[[R]]owId = extras.getLong(NotesDbAdapter.KEY_[[R]]OWID); |
− | if ( | + | if (m[[R]]owId != null) { |
String editTitle = extras.getString(NotesDbAdapter.KEY_TITLE); | String editTitle = extras.getString(NotesDbAdapter.KEY_TITLE); | ||
String editBody = extras.getString(NotesDbAdapter.KEY_BODY); | String editBody = extras.getString(NotesDbAdapter.KEY_BODY); | ||
− | + | mDb[[Help]]er.updateNote(mRowId, editTitle, editBody); | |
} | } | ||
fillData(); | fillData(); | ||
300行目: | 300行目: | ||
} | } | ||
===NoteEdit クラスの追加=== | ===NoteEdit クラスの追加=== | ||
− | public class NoteEdit extends | + | public class NoteEdit extends Acti[[vi]]ty { |
private EditText mTitleText; | private EditText mTitleText; | ||
private EditText mBodyText; | private EditText mBodyText; | ||
− | private Long | + | private Long m[[R]]owId; |
@Override | @Override | ||
309行目: | 309行目: | ||
// TODO Auto-generated method stub | // TODO Auto-generated method stub | ||
super.onCreate(savedInstanceState); | super.onCreate(savedInstanceState); | ||
− | setContentView(R.layout.note_edit); | + | setContentView([[R]].layout.note_edit); |
− | mTitleText = (EditText) findViewById(R.id.title); | + | mTitleText = (EditText) findViewById([[R]].id.title); |
− | mBodyText = (EditText) findViewById(R.id.body); | + | mBodyText = (EditText) findViewById([[R]].id.body); |
− | Button confirmButton = (Button) findViewById(R.id.confirm); | + | Button confirmButton = (Button) findViewById([[R]].id.confirm); |
confirmButton.setOnClickListener( | confirmButton.setOnClickListener( | ||
321行目: | 321行目: | ||
bundle.putString(NotesDbAdapter.KEY_TITLE, mTitleText.getText().toString()); | bundle.putString(NotesDbAdapter.KEY_TITLE, mTitleText.getText().toString()); | ||
bundle.putString(NotesDbAdapter.KEY_BODY, mBodyText.getText().toString()); | bundle.putString(NotesDbAdapter.KEY_BODY, mBodyText.getText().toString()); | ||
− | if ( | + | if (m[[R]]owId != null) { |
− | bundle.putLong(NotesDbAdapter. | + | bundle.putLong(NotesDbAdapter.KEY_[[R]]OWID, m[[R]]owId); |
} | } | ||
Intent mIntent = new Intent(); | Intent mIntent = new Intent(); | ||
mIntent.putExtras(bundle); | mIntent.putExtras(bundle); | ||
− | + | set[[R]]esult([[R]]ESULT_OK, mIntent); | |
finish(); | finish(); | ||
} | } | ||
332行目: | 332行目: | ||
); | ); | ||
− | + | m[[R]]owId = null; | |
Bundle extras = getIntent().getExtras(); | Bundle extras = getIntent().getExtras(); | ||
if (extras != null) { | if (extras != null) { | ||
String title = extras.getString(NotesDbAdapter.KEY_TITLE); | String title = extras.getString(NotesDbAdapter.KEY_TITLE); | ||
String body = extras.getString(NotesDbAdapter.KEY_BODY); | String body = extras.getString(NotesDbAdapter.KEY_BODY); | ||
− | + | m[[R]]owId = extras.getLong(NotesDbAdapter.KEY_[[R]]OWID); | |
if (title != null) { | if (title != null) { | ||
349行目: | 349行目: | ||
} | } | ||
− | === | + | ===[[Android]]Manifest.xml の編集=== |
− | *< | + | *<acti[[vi]]ty android:name=".NoteEdit"></acti[[vi]]ty>を追加 |
− | < | + | <acti[[vi]]ty android:name=".Notepadv2" android:label="@string/app_name"> |
: | : | ||
− | </ | + | </acti[[vi]]ty> |
− | < | + | <acti[[vi]]ty android:name=".NoteEdit"></acti[[vi]]ty> |
===ここまでで起動=== | ===ここまでで起動=== | ||
372行目: | 372行目: | ||
====onCreate()==== | ====onCreate()==== | ||
*メンバ変数の宣言 | *メンバ変数の宣言 | ||
− | private NotesDbAdapter | + | private NotesDbAdapter mDb[[Help]]er; |
@Override | @Override | ||
protected void onCreate(Bundle savedInstanceState) { | protected void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | super.onCreate(savedInstanceState); | ||
− | + | mDb[[Help]]er = new NotesDbAdapter(this); | |
− | + | mDb[[Help]]er.open(); | |
− | setContentView(R.layout.note_edit); | + | setContentView([[R]].layout.note_edit); |
− | mTitleText = (EditText) findViewById(R.id.title); | + | mTitleText = (EditText) findViewById([[R]].id.title); |
− | mBodyText = (EditText) findViewById(R.id.body); | + | mBodyText = (EditText) findViewById([[R]].id.body); |
− | Button confirmButton = (Button) findViewById(R.id.confirm); | + | Button confirmButton = (Button) findViewById([[R]].id.confirm); |
− | + | m[[R]]owId = savedInstanceState != null ? savedInstanceState.getLong(NotesDbAdapter.KEY_[[R]]OWID) | |
: null; | : null; | ||
− | if ( | + | if (m[[R]]owId == null) { |
Bundle extras = getIntent().getExtras(); | Bundle extras = getIntent().getExtras(); | ||
− | + | m[[R]]owId = extras != null ? extras.getLong(NotesDbAdapter.KEY_[[R]]OWID) | |
: null; | : null; | ||
} | } | ||
398行目: | 398行目: | ||
confirmButton.setOnClickListener(new View.OnClickListener() { | confirmButton.setOnClickListener(new View.OnClickListener() { | ||
− | public void onClick(View | + | public void onClick(View [[vi]]ew) { |
− | + | set[[R]]esult([[R]]ESULT_OK); | |
finish(); | finish(); | ||
} | } | ||
409行目: | 409行目: | ||
private void populateFields() { | private void populateFields() { | ||
− | if ( | + | if (m[[R]]owId != null) { |
− | Cursor note = | + | Cursor note = mDb[[Help]]er.fetchNote(mRowId); |
startManagingCursor(note); | startManagingCursor(note); | ||
mTitleText.setText(note.getString(note.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE))); | mTitleText.setText(note.getString(note.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE))); | ||
423行目: | 423行目: | ||
// TODO Auto-generated method stub | // TODO Auto-generated method stub | ||
super.onSaveInstanceState(outState); | super.onSaveInstanceState(outState); | ||
− | outState.putLong(NotesDbAdapter. | + | outState.putLong(NotesDbAdapter.KEY_[[R]]OWID, m[[R]]owId); |
} | } | ||
=====onPause()===== | =====onPause()===== | ||
433行目: | 433行目: | ||
saveState(); | saveState(); | ||
} | } | ||
− | ===== | + | =====on[[R]]esume()===== |
@Override | @Override | ||
− | protected void | + | protected void on[[R]]esume() { |
// TODO Auto-generated method stub | // TODO Auto-generated method stub | ||
− | super. | + | super.on[[R]]esume(); |
populateFields(); | populateFields(); | ||
} | } | ||
446行目: | 446行目: | ||
String body = mBodyText.getText().toString(); | String body = mBodyText.getText().toString(); | ||
− | if ( | + | if (m[[R]]owId == null) { |
− | long id = | + | long id = mDb[[Help]]er.createNote(title, body); |
if (id > 0) { | if (id > 0) { | ||
− | + | m[[R]]owId = id; | |
} | } | ||
} else { | } else { | ||
− | + | mDb[[Help]]er.updateNote(mRowId, title, body); | |
} | } | ||
} | } | ||
===Notepadv3 === | ===Notepadv3 === | ||
− | ==== | + | ====onActi[[vi]]tyResult()==== |
@Override | @Override | ||
− | protected void | + | protected void onActi[[vi]]tyResult(int requestCode, int resultCode, Intent intent) { |
− | super. | + | super.onActi[[vi]]tyResult(requestCode, resultCode, intent); |
fillData(); | fillData(); | ||
} | } | ||
469行目: | 469行目: | ||
Intent i = new Intent(this, NoteEdit.class); | Intent i = new Intent(this, NoteEdit.class); | ||
− | i.putExtra(NotesDbAdapter. | + | i.putExtra(NotesDbAdapter.KEY_[[R]]OWID, id); |
− | + | startActi[[vi]]tyForResult(i, ACTIVITY_EDIT); | |
} | } |
2020年2月16日 (日) 04:21時点における最新版
目次
- 1 Android Notepad チュートリアル
- 2 (1) 簡単なノートリストの作成
- 3 (2) Activity の追加、高度なレイアウトの使用など
- 4 (3)
Android Notepad チュートリアル
準備
ダウンロードして展開
(1) 簡単なノートリストの作成
プロジェクトの作成
- Create project from existing source を選択
- 解凍したフォルダから、NotepadCodeLab/Notepadv1 を選択
- Finish
NotesDbAdapter
用途
- NotesDbAdapterはSQLiteへのデータアクセスをカプセル化する。
宣言
- クラスの先頭で、テーブルのフィールドおよびデータベースが存在しない場合に生成する文字列を定義
- データベースは data という名前で、notes という _id、title、bodyの3つのフィールドをもつテーブルを一つ持つ。
コンストラクタ
- コンストラクタは、Context パラメータを取り、それにより Android OS との通信を許可。これは Android にアクセスする一般的な方法
- Activity クラスは Context を実装しているため、Contextが必要な時に渡すことができる。
メソッド
open()
- open()メソッドは、DatabaseHelper のインスタンスを呼び出す。
- DatabaseHelper は SQLiteOpenHelper のローカル実装。
- getWritableDatabase() で、データベースを作成、オープン
close()
- データベースを閉じてリリースを解放
createNote()
- 新しい note のためのタイトルと本文の文字列を引数に取り、note をデータベースに作成する
- 作成が成功した場合、_id を返す。
deleteNote()
- 行ID を引数に取り、note をデータベースから削除
fetchAllNotes()
- クエリーを発行して、カーソルを得る
- query() には、データベーステーブル名、取得したいカラムリスト、残りのフィールドは順に、selection、selectionArgs、 groupBy、 having、orderBy
- fetchNote()は、fetchAllNotes() と同様だが、行IDで1つの note を取得する
updateNote()
- 行ID、タイトル、本文を引数に取り、ContentValuesを使ってnoteを更新する。
レイアウト
LinearLayout の設定
すべての Android のXMLレイアウトのヘッダーは以下で始まらなければいけない
<?xml version="1.0" encoding="utf-8"?>.
次に、たいていの場合、以下の様なレイアウトを置く
LinearLayout
トップレベルのコンポーネントまたはレイアウトで Android のネームスペースを宣言する
xmlns:android="http://schemas.android.com/apk/res/android"
LinearLayout
<?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>
行のレイアウト
notes_row.xml
- res/layout に notes_row.xml を作成
<?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"/>
Notepadv1 クラスの編集
オーバーライドメソッド
onCreate()
- Activityが開始されたときに呼び出される。
- リソースの設定、ステートの設定を実施
onCreateOptionsMenu()
- Activity メニューの有効化
- ユーザーがメニューボタンをたたいた時に呼び出される
onOptionsItemSelected()
- 他の半数のメニューと等しい
- メニューから生成されるイベントを制御
基底クラスの変更
public class Notepadv1 extends ListActivity
onCreate()
private NotesDbAdapter mDbHelper; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.notepad_list); mDbHelper = new NotesDbAdapter(this); mDbHelper.open(); fillData(); }
- fillData() はまだ未作成
onCreateOptionsMenu()
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">Notepad v1</string> <string name="no_notes">No Notes Yet</string> <string name="menu_insert">Add Item</string> </resources>
public class Notepadv1 extends ListActivity { public static final int INSERT_ID = Menu.FIRST; :
@Override public boolean onCreateOptionsMenu(Menu menu) { // TODO Auto-generated method stub boolean result = super.onCreateOptionsMenu(menu); menu.add(0, INSERT_ID, 0, R.string.menu_insert); return result; }
onOptionsItemSelected()
@Override public boolean onOptionsItemSelected(MenuItem item) { // TODO Auto-generated method stub switch (item.getItemId()) { case INSERT_ID: createNote(); return true; } return super.onOptionsItemSelected(item); }
createNote()
public void createNote() { String noteName = "Note " + mNoteNumber++; mDbHelper.createNote(noteName, ""); fillData(); }
fillData()
private void fillData() { Cursor c = mDbHelper.fetchAllNotes(); startManagingCursor(c); String[] from = new String[] { NotesDbAdapter.KEY_TITLE }; int[] to = new int[] { R.id.text1 }; SimpleCursorAdapter notes = new SimpleCursorAdapter(this, R.layout.notes_row, c, from, to); setListAdapter(notes); }
ここまでで、起動
(2) Activity の追加、高度なレイアウトの使用など
- http://developer.android.com/resources/tutorials/notepad/notepad-ex2.html
- 2つめのActivityを作成しマニフェストに追加
- startActivityForResult()を使って非同期で別のActivityを呼び出す
- Bundle オブジェクトで Activity 間でデータを受け渡す
- 他のさらに高度なレイアウトの使用
- コンテキストメニューの作成
プロジェクトの作成
- 上記 Notepadv1 同様に、NotepadCodeLab/Notepadv2 からプロジェクトを作成する。
- /res/values/strings.xml に今回追加する機能の文字列が追加されている。
- Notepadv2 クラス には、カーソルを使うための mNotesCursor フィールドとともに、いくつかの定数が定義されている。
- fillData()では、mNotesCursor カーソルフィールドを使うようになっている。
- onCreate()は変更なし。
- いくつかのオーバーライドメソッドが記述されている(onCreateContextMenu(), onContextItemSelected(), onListItemClick() and onActivityResult())
表示されている note を削除するためのコンテキストメニューを追加する
registerForContextMenu()
- ListView のアイテムそれぞれに順にコンテキストメニューにregisterForContextMenu()を呼び出して登録
- onCreate() の最後に以下を追加
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.notes_list); mDbHelper = new NotesDbAdapter(this); mDbHelper.open(); fillData(); registerForContextMenu(getListView()); }
onCreateContextMenu()
@Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); // TODO: fill in rest of method super.onCreateContextMenu(menu, v, menuInfo); menu.add(0, DELETE_ID, 0, R.string.menu_delete); }
onContextItemSelected()
@Override public boolean onContextItemSelected(MenuItem item) { // TODO: fill in rest of method switch(item.getItemId()) { case DELETE_ID: AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); mDbHelper.deleteNote(info.id); fillData(); return true; } return super.onContextItemSelected(item); }
onActivityResult()
@Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { // TODO Auto-generated method stub 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; } }
createNote()
private void createNote() { // TODO: fill in implementation Intent i = new Intent(this, NoteEdit.class); startActivityForResult(i, ACTIVITY_CREATE); }
onListItemClick()
@Override protected void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); // TODO: fill in rest of method 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); }
onActivityResult()
@Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); // TODO: fill in rest of method 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; } }
NoteEdit クラスの追加
public class NoteEdit extends Activity { private EditText mTitleText; private EditText mBodyText; private Long mRowId; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.note_edit); mTitleText = (EditText) findViewById(R.id.title); mBodyText = (EditText) findViewById(R.id.body); Button confirmButton = (Button) findViewById(R.id.confirm); confirmButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { 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); } Intent mIntent = new Intent(); mIntent.putExtras(bundle); setResult(RESULT_OK, mIntent); finish(); } } ); 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); } } } }
AndroidManifest.xml の編集
<activity android:name=".Notepadv2" android:label="@string/app_name"> : </activity> <activity android:name=".NoteEdit"></activity>
ここまでで起動
コンテキストメニューは、コントロールパッド長押し
(3)
- ライフサイクルイベントの利用
- アプリケーション
プロジェクトの作成
- 同様に、Notepadv3 からプロジェクトを作成。
- 上記 Notepadv2 を完成させた状態と Notepadv3 は同じ
NoteEdit クラス
onCreate()
- メンバ変数の宣言
private NotesDbAdapter mDbHelper;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mDbHelper = new NotesDbAdapter(this); mDbHelper.open(); setContentView(R.layout.note_edit); mTitleText = (EditText) findViewById(R.id.title); mBodyText = (EditText) findViewById(R.id.body); Button confirmButton = (Button) findViewById(R.id.confirm); mRowId = savedInstanceState != null ? savedInstanceState.getLong(NotesDbAdapter.KEY_ROWID) : null; if (mRowId == null) { Bundle extras = getIntent().getExtras(); mRowId = extras != null ? extras.getLong(NotesDbAdapter.KEY_ROWID) : null; } populateFields(); confirmButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { setResult(RESULT_OK); finish(); } }); }
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))); } }
オーバーライドメソッドを実装
onSaveInstanceState()
@Override protected void onSaveInstanceState(Bundle outState) { // TODO Auto-generated method stub super.onSaveInstanceState(outState); outState.putLong(NotesDbAdapter.KEY_ROWID, mRowId); }
onPause()
- saveState()は後ほど作成
@Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); saveState(); }
onResume()
@Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); populateFields(); }
saveState() を追加
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); } }
Notepadv3
onActivityResult()
@Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); fillData(); }
onListItemClick()
@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); }
© 2006 矢木浩人