Create a Notepad and To-do list combined app in Android
DownloadKeywords: TabHost ListView ExpandableListActivity SQLite SimpleCursorAdapter SimpleCursorTreeAdapter PreferenceActivity AlertDialog ContextMenu Spinner Gallery ScrollView Camera
Contents- Overview
- Create a new Eclipse Android project
- Define the Data model
- The Android Manifest file
- The Application class
- Develop the UI
- The Browse tab
- The Manage tab
- The Preferences screen
- The Alert Dialog
- The Context Menu
- The Edit Page
- Image Capture
10. The Alert Dialog
We will now create the various menus and dialogs in the application. Also, we will handle the various onclick events generated when user clicks an item.We show this dialog when user clicks the new note button at the bottom of the screen. Add the following line to the ImageButton tag in tab_browse.xml layout file.
android:onClick="onClick"We need to implement the same onClick function in BrowseActivity class to handle the on click event.
public void onClick(View v) { switch (v.getId()) { case R.id.new_btn: optionsDialog.show(); break; } }Where optionsDialog is an AlertDialog. Add the following lines of code in the onCreate() method.
AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Choose an Option"); builder.setItems(R.array.new_note_arr, dialogListener); optionsDialog = builder.create();The item array comes from a static file. Create arrays.xml under res/values directory.
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="new_note_arr"> <item>Note</item> <item>Checklist</item> <item>Snapshot</item> </string-array> </resources>We create dialogListener to handle on click events on each item.
private DialogInterface.OnClickListener dialogListener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (dialog == optionsDialog) { Intent intent = new Intent(); switch (which) { case 0: intent.setClass(BrowseActivity.this, BasicActivity.class); break; case 1: intent.setClass(BrowseActivity.this, ChecklistActivity.class); break; case 2: intent.setClass(BrowseActivity.this, SnapshotActivity.class); break; } startActivity(intent); } } };That's all we need to do to implement the dialog. Previously, we deferred implemention of onItemClick() method when a particular note is clicked in the ListView. We will do it now. Update the onItemClick() method as follows.
@Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Note note = new Note(id); note.load(SmartPad.db); Class claz = null; String type = note.getType(); if (Note.BASIC.equals(type)) { claz = BasicActivity.class; } else if (Note.CHECKLIST.equals(type)) { claz = ChecklistActivity.class; } else if (Note.SNAPSHOT.equals(type)) { claz = SnapshotActivity.class; } Intent intent = new Intent(); intent.setClass(this, claz); intent.putExtra(Note.COL_ID, id); startActivity(intent); }You must have noticed, we call show() on optionsDialog to display the dialog when the new note button is clicked. However, Android provides a neat way to manage dialogs when there are multiple dialogs in a screen. We will use this approach in the Manage tab.
@Override protected Dialog onCreateDialog(int id) { switch (id) { case DIALOG_NEW_CATEGORY: AlertDialog categoryDialog = new AlertDialog.Builder(this) .setTitle("Enter Category Name") .setView(categoryNameEdit) .setCancelable(false) .setPositiveButton("Ok", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // TODO persist new category } }) .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } }) .create(); return categoryDialog; } return super.onCreateDialog(id); } @Override protected void onPrepareDialog(int id, Dialog dialog) { super.onPrepareDialog(id, dialog); switch (id) { case DIALOG_NEW_CATEGORY: break; case DIALOG_RENAME_CATEGORY: break; } }The onPrepareDialog() method is not required but is useful when some modification is to be done before showing the dialog. Here is how the dialog is shown.
showDialog(DIALOG_NEW_CATEGORY);We just pass the dialog id for the dialog that is to be shown.
11. The Context Menu
Another useful thing is context menu which allows user to take action on a particular list item. Here is how it is implemented. The following line in onCreate() method registers the ListView for context menu,
registerForContextMenu(noteList);Next we need to override onCreateContextMenu() and onContextItemSelected() methods in Activity.
@Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { if (v.getId() == R.id.note_list) { getMenuInflater().inflate(R.menu.contextmenu_browse, menu); menu.setHeaderTitle("Choose an Option"); menu.setHeaderIcon(R.drawable.ic_dialog_menu_generic); } } @Override public boolean onContextItemSelected(MenuItem item) { AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); switch (item.getItemId()) { case R.id.menu_edit: openNote(info.id, this); break; case R.id.menu_delete: Note note = new Note(info.id); note.delete(SmartPad.db); SimpleCursorAdapter adapter = (SimpleCursorAdapter) noteList.getAdapter(); adapter.getCursor().requery(); adapter.notifyDataSetChanged(); break; } return true; }We created a contextmenu_browse.xml file under res/menu to declare the menu items.
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/menu_edit" android:title="@string/edit" /> <item android:id="@+id/menu_delete" android:title="@string/delete" /> </menu>The Manage tab also has context menu but there is a small difference since it need to be shown for a group item as well as a child item.
@Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { if (v.getId() == android.R.id.list) { ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo; int type = ExpandableListView.getPackedPositionType(info.packedPosition); getMenuInflater().inflate(R.menu.contextmenu_manage, menu); menu.setHeaderTitle("Choose an Option"); menu.setHeaderIcon(R.drawable.ic_dialog_menu_generic); if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) { // code specific to a child item } else if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) { // code specific to a group item } } } @Override public boolean onContextItemSelected(MenuItem item) { ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) item.getMenuInfo(); int type = ExpandableListView.getPackedPositionType(info.packedPosition); if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) { // code specific to a child item } else if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) { // code specific to a group item } switch (item.getItemId()) { case R.id.menu_edit: // TODO edit break; case R.id.menu_delete: // TODO delete break; } SimpleCursorTreeAdapter adapter = (SimpleCursorTreeAdapter) getExpandableListAdapter(); adapter.getCursor().requery(); adapter.notifyDataSetChanged(); return true; }
In the next chapter we discuss how to implement the Settings screen using PreferenceActivity.