Notepad Tutorialで学ぶAndroidアプリのSQLite講座3

SQLite講座12で、Notepad Tutorial: Exercise 1を突破。

SQLite講座3からNotepad Exercise 2の始まり始まりー。






Notepad Tutorial: Exercise 2で勉強すること

新しいActivityを追加
非同期で、別のActivityを立ち上げる
Actity間でデータをやり取りする
少し難しいレイアウトの使い方
コンテクストメニューの作り方


Step1: 準備編


Exercise 1でやったように、Existing projectからNotepadv2を作成。

note_edit.xmlで
match_parentのところでString types not allowedというerrorが出てくる。

あとR.javaが生成できなくてerrorが出てくる。


意味プーです。
とうことで、Google先生に聞いたところ下記の方法でエラーが消えました。

Android 1.6をターゲットにしているのでエラーが発生する
Notepadv2を右クリックしてpropertiesを選択、Androidを選択してProject Build targetをAndroid 1.6からAndroid 4.1.2に引き上げる。(Android 2.3以上なら多分大丈夫)

Project -> Clean でプロジェクトをキレイにする。

これで、エラーが消えます。


でも、warningが出てくる。
startManagingCursor deprecated

調べてみるとstartManagingCursorは、fragmentの兼ね合いで、何か使い方が変わったらしいです。よくわからないので、Android 4.1.2をAndroid 2.3.3に引き下げて、warningが出ないようにしました。

とりあえず、新しいバージョンではstartManagingCursorの使い方が異なるというのを少し気に留めて次に進むなり。

Notepadv2.javaを眺めて、ContextMenuって何だろうと思いつつ、layoutフォルダを見て、note_edit.xmlという新しいレイアウトファイルを見つけて、次のステップへ。


Step2: コンテクストメニューを作成


そもそもコンテクストメニューって何?って調べてみたところ、画面を長押しすると現れるメニュー画面とのことでした。


コンテクストメニューの作り方。
まずNotepadv2のonCreateの最後でregisterForContextMenu()にListViewを渡す。

registerForContextMenu(getListView());

これでListViewの個々のアイテムがコンテクストメニューに登録されます。


onCreateContextMenu()にmenu.addでノートを削除するmenuを追加する。

    @Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		super.onCreateContextMenu(menu, v, menuInfo);
		menu.add(0, DELETE_ID, 0, R.string.menu_delete);
	}

menu.addの引数
最初の引数はグループID(0はなし)、次はユニークID、次は並び順(0はなんでもいい)、最後に表示する文字


Step3: 削除するノートを選択


選択したListIDを調べて、それがDELETE_IDなら、長押しした場所のノートの調べて、その情報をdeleteNoteに渡して、ノートを削除します。

    @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);
	}

import android.widget.AdapterView.AdapterContextMenuInfo;
を追加しておく。

info.idがListViewでのノートの場所を指しているそうです。


Step4: 新しいActivityを呼び出す(新しいノートの作成)


createNoteが呼ばれたときに、intentを作って、それをstartActivityForResultに渡してActivityを起動します。

    private void createNote() {
    	Intent i = new Intent(this, NoteEdit.class);
    	startActivityForResult(i, ACTIVITY_CREATE);
    }


intentは、activityの起動方法みたいなのを記載しているやつです。

intentはandroidからくるリクエストを振り分ける機能があるので、
contextのthisを渡してあげる。(正直よくわからないけど、あまり気にしない!)

startActivityForResultのときにintentとACTIVITY_CREATEを渡して上げる。

新しいactivityが終了して、
onActivityResultが呼ばれたときに目印になるのがACTIVITY_CREATEです。


Step5: 新しいActivityを呼び出す(ノートの編集)


リストにあるノートを選択して、ノートの編集をするためのメソッドを書きましょうー。

    @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);
    }

mNotesCursorを直接使わずに、わざわさローカル変数にしてアクセスしている理由は、そのほうがパフォーマンスが上がるんだってさ。
Cursor c = mNotesCursor;

putExtraをつけることで、intentにいろんな値を入れることができるよ。
putExtraの第一引数は値の名前、第二引数は値そのもの。


Step6: 新しいActivityが終了したときのコールバック


startActivityForResultで新しいActivityを呼び出すと、
新しいActivityが終了するときに、onActivityResultが呼ばれます。

で、今回はそのコールバックの処理をしましょうー。

    @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;
        }

    }


新しいActivityを呼び出してそこで新しいノートを作ったり編集したりした後に、
onActivityResultを捕まえて、ノートをdbに保存します。



SQLite講座3はここまで!
次の回で、Exercise 2が完了予定です。

コメントを残す

メールアドレスが公開されることはありません。