| ページ一覧 | ブログ | twitter |  書式 | 書式(表) |

MyMemoWiki

Android Notepad チュートリアル

提供: MyMemoWiki
ナビゲーションに移動 検索に移動

目次

Android Notepad チュートリアル

Android | Java | Eclipse |

準備

ダウンロードして展開

(1) 簡単なノートリストの作成

  • 新しいノートを追加する(まだ編集はできない)
  • ListActivity を使ってみる
  • SQLiteを使ってみる

プロジェクトの作成

  • Create project from existing source を選択
  • 解凍したフォルダから、NotepadCodeLab/Notepadv1 を選択
  • Finish

0146 android notepad01.jpg

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レイアウトのヘッダーは以下で始まらなければいけない
  1. <?xml version="1.0" encoding="utf-8"?>.
次に、たいていの場合、以下の様なレイアウトを置く
  1. LinearLayout
トップレベルのコンポーネントまたはレイアウトで Android のネームスペースを宣言する
  1. xmlns:android="http://schemas.android.com/apk/res/android"

LinearLayout

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="wrap_content"
  4. android:layout_height="wrap_content">
  5. <ListView android:id="@android:id/list"
  6. android:layout_width="wrap_content"
  7. android:layout_height="wrap_content"/>
  8. <TextView android:id="@android:id/empty"
  9. android:layout_width="wrap_content"
  10. android:layout_height="wrap_content"
  11. android:text="@string/no_notes"/>
  12. </LinearLayout>

行のレイアウト

notes_row.xml

  • res/layout に notes_row.xml を作成
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <TextView android:id="@+id/text1"
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:layout_width="wrap_content"
  5. android:layout_height="wrap_content"/>

Notepadv1 クラスの編集

オーバーライドメソッド

onCreate()
  • Activityが開始されたときに呼び出される。
  • リソースの設定、ステートの設定を実施
onCreateOptionsMenu()
  • Activity メニューの有効化
  • ユーザーがメニューボタンをたたいた時に呼び出される
onOptionsItemSelected()
  • 他の半数のメニューと等しい
  • メニューから生成されるイベントを制御

基底クラスの変更

  1. public class Notepadv1 extends ListActivity

onCreate()

  1. private NotesDbAdapter mDbHelper;
  2.  
  3. /** Called when the activity is first created. */
  4. @Override
  5. public void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.notepad_list);
  8. mDbHelper = new NotesDbAdapter(this);
  9. mDbHelper.open();
  10. fillData();
  11. }
  • fillData() はまだ未作成

onCreateOptionsMenu()

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <string name="app_name">Notepad v1</string>
  4. <string name="no_notes">No Notes Yet</string>
  5. <string name="menu_insert">Add Item</string>
  6. </resources>


  1. public class Notepadv1 extends ListActivity {
  2. public static final int INSERT_ID = Menu.FIRST;
  1. @Override
  2. public boolean onCreateOptionsMenu(Menu menu) {
  3. // TODO Auto-generated method stub
  4. boolean result = super.onCreateOptionsMenu(menu);
  5. menu.add(0, INSERT_ID, 0, R.string.menu_insert);
  6. return result;
  7. }

onOptionsItemSelected()

  1. @Override
  2. public boolean onOptionsItemSelected(MenuItem item) {
  3. // TODO Auto-generated method stub
  4. switch (item.getItemId()) {
  5. case INSERT_ID:
  6. createNote();
  7. return true;
  8. }
  9. return super.onOptionsItemSelected(item);
  10. }

createNote()

  1. public void createNote() {
  2. String noteName = "Note " + mNoteNumber++;
  3. mDbHelper.createNote(noteName, "");
  4. fillData();
  5. }

fillData()

  1. private void fillData() {
  2. Cursor c = mDbHelper.fetchAllNotes();
  3. startManagingCursor(c);
  4. String[] from = new String[] { NotesDbAdapter.KEY_TITLE };
  5. int[] to = new int[] { R.id.text1 };
  6. SimpleCursorAdapter notes =
  7. new SimpleCursorAdapter(this, R.layout.notes_row, c, from, to);
  8. setListAdapter(notes);
  9. }

ここまでで、起動

0147 android notepad02.jpg

(2) Activity の追加、高度なレイアウトの使用など

プロジェクトの作成

  • 上記 Notepadv1 同様に、NotepadCodeLab/Notepadv2 からプロジェクトを作成する。
  • /res/values/strings.xml に今回追加する機能の文字列が追加されている。
  • Notepadv2 クラス には、カーソルを使うための mNotesCursor フィールドとともに、いくつかの定数が定義されている。
  • fillData()では、mNotesCursor カーソルフィールドを使うようになっている。
  • onCreate()は変更なし。
  • いくつかのオーバーライドメソッドが記述されている(onCreateContextMenu(), onContextItemSelected(), onListItemClick() and onActivityResult())

表示されている note を削除するためのコンテキストメニューを追加する

registerForContextMenu()

  • ListView のアイテムそれぞれに順にコンテキストメニューにregisterForContextMenu()を呼び出して登録
  • onCreate() の最後に以下を追加
  1. @Override
  2. public void onCreate(Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. setContentView(R.layout.notes_list);
  5. mDbHelper = new NotesDbAdapter(this);
  6. mDbHelper.open();
  7. fillData();
  8. registerForContextMenu(getListView());
  9. }

onCreateContextMenu()

  1. @Override
  2. public void onCreateContextMenu(ContextMenu menu, View v,
  3. ContextMenuInfo menuInfo) {
  4. super.onCreateContextMenu(menu, v, menuInfo);
  5. // TODO: fill in rest of method
  6. super.onCreateContextMenu(menu, v, menuInfo);
  7. menu.add(0, DELETE_ID, 0, R.string.menu_delete);
  8. }

onContextItemSelected()

  1. @Override
  2. public boolean onContextItemSelected(MenuItem item) {
  3. // TODO: fill in rest of method
  4. switch(item.getItemId()) {
  5. case DELETE_ID:
  6. AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
  7. mDbHelper.deleteNote(info.id);
  8. fillData();
  9. return true;
  10. }
  11. return super.onContextItemSelected(item);
  12. }

onActivityResult()

  1. @Override
  2. protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
  3. // TODO Auto-generated method stub
  4. super.onActivityResult(requestCode, resultCode, intent);
  5. Bundle extras = intent.getExtras();
  6. switch(requestCode) {
  7. case ACTIVITY_CREATE:
  8. String title = extras.getString(NotesDbAdapter.KEY_TITLE);
  9. String body = extras.getString(NotesDbAdapter.KEY_BODY);
  10. mDbHelper.createNote(title, body);
  11. fillData();
  12. break;
  13. case ACTIVITY_EDIT:
  14. Long mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);
  15. if (mRowId != null) {
  16. String editTitle = extras.getString(NotesDbAdapter.KEY_TITLE);
  17. String editBody = extras.getString(NotesDbAdapter.KEY_BODY);
  18. mDbHelper.updateNote(mRowId, editTitle, editBody);
  19. }
  20. fillData();
  21. break;
  22. }
  23. }

createNote()

  1. private void createNote() {
  2. // TODO: fill in implementation
  3. Intent i = new Intent(this, NoteEdit.class);
  4. startActivityForResult(i, ACTIVITY_CREATE);
  5. }

onListItemClick()

  1. @Override
  2. protected void onListItemClick(ListView l, View v, int position, long id) {
  3. super.onListItemClick(l, v, position, id);
  4.  
  5. // TODO: fill in rest of method
  6. Cursor c = mNotesCursor;
  7. c.moveToPosition(position);
  8. Intent i = new Intent(this, NoteEdit.class);
  9. i.putExtra(NotesDbAdapter.KEY_ROWID, id);
  10. i.putExtra(NotesDbAdapter.KEY_TITLE,
  11. c.getString(c.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE)));
  12. i.putExtra(NotesDbAdapter.KEY_BODY,
  13. c.getString(c.getColumnIndexOrThrow(NotesDbAdapter.KEY_BODY)));
  14. startActivityForResult(i, ACTIVITY_EDIT);
  15. }

onActivityResult()

  1. @Override
  2. protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
  3. super.onActivityResult(requestCode, resultCode, intent);
  4. // TODO: fill in rest of method
  5. Bundle extras = intent.getExtras();
  6. switch(requestCode) {
  7. case ACTIVITY_CREATE:
  8. String title = extras.getString(NotesDbAdapter.KEY_TITLE);
  9. String body = extras.getString(NotesDbAdapter.KEY_BODY);
  10. mDbHelper.createNote(title, body);
  11. fillData();
  12. break;
  13. case ACTIVITY_EDIT:
  14. Long mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);
  15. if (mRowId != null) {
  16. String editTitle = extras.getString(NotesDbAdapter.KEY_TITLE);
  17. String editBody = extras.getString(NotesDbAdapter.KEY_BODY);
  18. mDbHelper.updateNote(mRowId, editTitle, editBody);
  19. }
  20. fillData();
  21. break;
  22. }
  23. }

NoteEdit クラスの追加

  1. public class NoteEdit extends Activity {
  2. private EditText mTitleText;
  3. private EditText mBodyText;
  4. private Long mRowId;
  5. @Override
  6. protected void onCreate(Bundle savedInstanceState) {
  7. // TODO Auto-generated method stub
  8. super.onCreate(savedInstanceState);
  9. setContentView(R.layout.note_edit);
  10. mTitleText = (EditText) findViewById(R.id.title);
  11. mBodyText = (EditText) findViewById(R.id.body);
  12. Button confirmButton = (Button) findViewById(R.id.confirm);
  13. confirmButton.setOnClickListener(
  14. new View.OnClickListener() {
  15. @Override
  16. public void onClick(View v) {
  17. Bundle bundle = new Bundle();
  18. bundle.putString(NotesDbAdapter.KEY_TITLE, mTitleText.getText().toString());
  19. bundle.putString(NotesDbAdapter.KEY_BODY, mBodyText.getText().toString());
  20. if (mRowId != null) {
  21. bundle.putLong(NotesDbAdapter.KEY_ROWID, mRowId);
  22. }
  23. Intent mIntent = new Intent();
  24. mIntent.putExtras(bundle);
  25. setResult(RESULT_OK, mIntent);
  26. finish();
  27. }
  28. }
  29. );
  30. mRowId = null;
  31. Bundle extras = getIntent().getExtras();
  32. if (extras != null) {
  33. String title = extras.getString(NotesDbAdapter.KEY_TITLE);
  34. String body = extras.getString(NotesDbAdapter.KEY_BODY);
  35. mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);
  36. if (title != null) {
  37. mTitleText.setText(title);
  38. }
  39. if (body != null) {
  40. mBodyText.setText(body);
  41. }
  42. }
  43. }
  44. }

AndroidManifest.xml の編集

  • <activity android:name=".NoteEdit"></activity>を追加
  1. <activity android:name=".Notepadv2" android:label="@string/app_name">
  2. :
  3. </activity>
  4. <activity android:name=".NoteEdit"></activity>

ここまでで起動

0148 android notepad03.jpg

コンテキストメニューは、コントロールパッド長押し

0149 android notepad04.jpg

(3)

  • ライフサイクルイベントの利用
  • アプリケーション

プロジェクトの作成

  • 同様に、Notepadv3 からプロジェクトを作成。
  • 上記 Notepadv2 を完成させた状態と Notepadv3 は同じ

NoteEdit クラス

onCreate()

  • メンバ変数の宣言
  1. private NotesDbAdapter mDbHelper;
  1. @Override
  2. protected void onCreate(Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. mDbHelper = new NotesDbAdapter(this);
  5. mDbHelper.open();
  6. setContentView(R.layout.note_edit);
  7. mTitleText = (EditText) findViewById(R.id.title);
  8. mBodyText = (EditText) findViewById(R.id.body);
  9. Button confirmButton = (Button) findViewById(R.id.confirm);
  10. mRowId = savedInstanceState != null ? savedInstanceState.getLong(NotesDbAdapter.KEY_ROWID)
  11. : null;
  12. if (mRowId == null) {
  13. Bundle extras = getIntent().getExtras();
  14. mRowId = extras != null ? extras.getLong(NotesDbAdapter.KEY_ROWID)
  15. : null;
  16. }
  17. populateFields();
  18. confirmButton.setOnClickListener(new View.OnClickListener() {
  19.  
  20. public void onClick(View view) {
  21. setResult(RESULT_OK);
  22. finish();
  23. }
  24. });
  25. }

populateFields() を作成

  1. private void populateFields() {
  2. if (mRowId != null) {
  3. Cursor note = mDbHelper.fetchNote(mRowId);
  4. startManagingCursor(note);
  5. mTitleText.setText(note.getString(note.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE)));
  6. mBodyText.setText(note.getString(note.getColumnIndexOrThrow(NotesDbAdapter.KEY_BODY)));
  7. }
  8. }

オーバーライドメソッドを実装

onSaveInstanceState()
  1. @Override
  2. protected void onSaveInstanceState(Bundle outState) {
  3. // TODO Auto-generated method stub
  4. super.onSaveInstanceState(outState);
  5. outState.putLong(NotesDbAdapter.KEY_ROWID, mRowId);
  6. }
onPause()
  • saveState()は後ほど作成
  1. @Override
  2. protected void onPause() {
  3. // TODO Auto-generated method stub
  4. super.onPause();
  5. saveState();
  6. }
onResume()
  1. @Override
  2. protected void onResume() {
  3. // TODO Auto-generated method stub
  4. super.onResume();
  5. populateFields();
  6. }

saveState() を追加

  1. private void saveState() {
  2. String title = mTitleText.getText().toString();
  3. String body = mBodyText.getText().toString();
  4. if (mRowId == null) {
  5. long id = mDbHelper.createNote(title, body);
  6. if (id > 0) {
  7. mRowId = id;
  8. }
  9. } else {
  10. mDbHelper.updateNote(mRowId, title, body);
  11. }
  12. }

Notepadv3

onActivityResult()

  1. @Override
  2. protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
  3. super.onActivityResult(requestCode, resultCode, intent);
  4. fillData();
  5. }

onListItemClick()

  1. @Override
  2. protected void onListItemClick(ListView l, View v, int position, long id) {
  3. super.onListItemClick(l, v, position, id);
  4.  
  5. Intent i = new Intent(this, NoteEdit.class);
  6. i.putExtra(NotesDbAdapter.KEY_ROWID, id);
  7. startActivityForResult(i, ACTIVITY_EDIT);
  8. }