diff options
| author | Scott Main <smain@google.com> | 2010-11-29 11:16:13 -0800 |
|---|---|---|
| committer | Scott Main <smain@google.com> | 2010-12-02 12:09:38 -0800 |
| commit | a00a0e7f7de72883f6f1523e989a7c1d18ac53b7 (patch) | |
| tree | 01aaf00a31e1cf0d89a4081bc20d6a9a4c079f6a /samples/NotePad | |
| parent | 7fd3f4150436e85a21a3ddb19e06ef7a68b2dd64 (diff) | |
| download | android_development-a00a0e7f7de72883f6f1523e989a7c1d18ac53b7.tar.gz android_development-a00a0e7f7de72883f6f1523e989a7c1d18ac53b7.tar.bz2 android_development-a00a0e7f7de72883f6f1523e989a7c1d18ac53b7.zip | |
This is a manual merge of Ib7ea41079f3b268f3be1f86febdb1caed98bdd8e
Which includes the following:
- inflating menus from XML and supporting API Level 3 without the need
for version qualifiers on resource directories.
- to NOT include items in the options menu based on the 'selected' item
(that's what a context menu is for).
- include all drawables in the app, instead of using system resources.
Add features:
- the ability to edit the note title through the context menu
- disable menu items in the editor based on menu groups
- add a "save" button to the editor instead of assuming BACK functionality
- and show the title of the current note in the activity title.
Plus, this change adds Holo themes and items to the action bar.
And fix a bug in NoteEditor: the constants used for the column indexes caused the title
and note text to be saved incorrectly---removed them and instead perform column index
lookup on the notes cursor.
Change-Id: I6e7a693a35f5dc2da423982869dd871c4c171e5b
Diffstat (limited to 'samples/NotePad')
30 files changed, 264 insertions, 370 deletions
diff --git a/samples/NotePad/AndroidManifest.xml b/samples/NotePad/AndroidManifest.xml index 2e0d85a77..ddf481882 100644 --- a/samples/NotePad/AndroidManifest.xml +++ b/samples/NotePad/AndroidManifest.xml @@ -22,8 +22,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.notepad" > - <uses-sdk android:targetSdkVersion="4" android:minSdkVersion="3"/> - + <uses-sdk android:minSdkVersion="Froyo" /> <application android:icon="@drawable/app_notes" android:label="@string/app_name" > @@ -53,8 +52,7 @@ </activity> <activity android:name="NoteEditor" - android:theme="@android:style/Theme.Light" - android:label="@string/title_note" + android:theme="@android:style/Theme.Light.Holo" android:screenOrientation="sensor" android:configChanges="keyboardHidden|orientation" > @@ -83,7 +81,8 @@ <activity android:name="TitleEditor" android:label="@string/title_edit_title" - android:theme="@android:style/Theme.Dialog" + android:icon="@drawable/ic_menu_edit" + android:theme="@android:style/Theme.Holo.Dialog" android:windowSoftInputMode="stateVisible"> <!-- This activity implements an alternative action that can be performed on notes: editing their title. It can be used as diff --git a/samples/NotePad/res/drawable-hdpi-v6/app_notes.png b/samples/NotePad/res/drawable-hdpi-v6/app_notes.png Binary files differdeleted file mode 100644 index 34918237f..000000000 --- a/samples/NotePad/res/drawable-hdpi-v6/app_notes.png +++ /dev/null diff --git a/samples/NotePad/res/drawable-hdpi/app_notes.png b/samples/NotePad/res/drawable-hdpi/app_notes.png Binary files differindex 258d3d167..34918237f 100755..100644 --- a/samples/NotePad/res/drawable-hdpi/app_notes.png +++ b/samples/NotePad/res/drawable-hdpi/app_notes.png diff --git a/samples/NotePad/res/drawable-hdpi/ic_menu_compose.png b/samples/NotePad/res/drawable-hdpi/ic_menu_compose.png Binary files differnew file mode 100644 index 000000000..6ad379e22 --- /dev/null +++ b/samples/NotePad/res/drawable-hdpi/ic_menu_compose.png diff --git a/samples/NotePad/res/drawable-hdpi/ic_menu_delete.png b/samples/NotePad/res/drawable-hdpi/ic_menu_delete.png Binary files differnew file mode 100644 index 000000000..2aed26a1b --- /dev/null +++ b/samples/NotePad/res/drawable-hdpi/ic_menu_delete.png diff --git a/samples/NotePad/res/drawable-hdpi/ic_menu_edit.png b/samples/NotePad/res/drawable-hdpi/ic_menu_edit.png Binary files differnew file mode 100644 index 000000000..602dd1041 --- /dev/null +++ b/samples/NotePad/res/drawable-hdpi/ic_menu_edit.png diff --git a/samples/NotePad/res/drawable-hdpi/ic_menu_revert.png b/samples/NotePad/res/drawable-hdpi/ic_menu_revert.png Binary files differnew file mode 100644 index 000000000..11860a4e1 --- /dev/null +++ b/samples/NotePad/res/drawable-hdpi/ic_menu_revert.png diff --git a/samples/NotePad/res/drawable-hdpi/ic_menu_save.png b/samples/NotePad/res/drawable-hdpi/ic_menu_save.png Binary files differnew file mode 100644 index 000000000..fc26c5d5f --- /dev/null +++ b/samples/NotePad/res/drawable-hdpi/ic_menu_save.png diff --git a/samples/NotePad/res/drawable-hdpi-v6/live_folder_notes.png b/samples/NotePad/res/drawable-hdpi/live_folder_notes.png Binary files differindex c6d26f5cb..c6d26f5cb 100644 --- a/samples/NotePad/res/drawable-hdpi-v6/live_folder_notes.png +++ b/samples/NotePad/res/drawable-hdpi/live_folder_notes.png diff --git a/samples/NotePad/res/drawable-ldpi-v6/app_notes.png b/samples/NotePad/res/drawable-ldpi/app_notes.png Binary files differindex 8432ce63b..8432ce63b 100644 --- a/samples/NotePad/res/drawable-ldpi-v6/app_notes.png +++ b/samples/NotePad/res/drawable-ldpi/app_notes.png diff --git a/samples/NotePad/res/drawable-ldpi-v6/live_folder_notes.png b/samples/NotePad/res/drawable-ldpi/live_folder_notes.png Binary files differindex d547cbf2c..d547cbf2c 100644 --- a/samples/NotePad/res/drawable-ldpi-v6/live_folder_notes.png +++ b/samples/NotePad/res/drawable-ldpi/live_folder_notes.png diff --git a/samples/NotePad/res/drawable-mdpi/app_notes.png b/samples/NotePad/res/drawable-mdpi/app_notes.png Binary files differdeleted file mode 100644 index 0479138d1..000000000 --- a/samples/NotePad/res/drawable-mdpi/app_notes.png +++ /dev/null diff --git a/samples/NotePad/res/drawable-mdpi/live_folder_notes.png b/samples/NotePad/res/drawable-mdpi/live_folder_notes.png Binary files differdeleted file mode 100644 index ac54a49ed..000000000 --- a/samples/NotePad/res/drawable-mdpi/live_folder_notes.png +++ /dev/null diff --git a/samples/NotePad/res/drawable-mdpi-v6/app_notes.png b/samples/NotePad/res/drawable/app_notes.png Binary files differindex 81d1c22e1..81d1c22e1 100644 --- a/samples/NotePad/res/drawable-mdpi-v6/app_notes.png +++ b/samples/NotePad/res/drawable/app_notes.png diff --git a/samples/NotePad/res/drawable/ic_menu_compose.png b/samples/NotePad/res/drawable/ic_menu_compose.png Binary files differnew file mode 100644 index 000000000..1b4733e42 --- /dev/null +++ b/samples/NotePad/res/drawable/ic_menu_compose.png diff --git a/samples/NotePad/res/drawable/ic_menu_delete.png b/samples/NotePad/res/drawable/ic_menu_delete.png Binary files differnew file mode 100755 index 000000000..7d954943d --- /dev/null +++ b/samples/NotePad/res/drawable/ic_menu_delete.png diff --git a/samples/NotePad/res/drawable/ic_menu_edit.png b/samples/NotePad/res/drawable/ic_menu_edit.png Binary files differnew file mode 100755 index 000000000..41a9c2e20 --- /dev/null +++ b/samples/NotePad/res/drawable/ic_menu_edit.png diff --git a/samples/NotePad/res/drawable/ic_menu_revert.png b/samples/NotePad/res/drawable/ic_menu_revert.png Binary files differnew file mode 100644 index 000000000..e7e04f531 --- /dev/null +++ b/samples/NotePad/res/drawable/ic_menu_revert.png diff --git a/samples/NotePad/res/drawable/ic_menu_save.png b/samples/NotePad/res/drawable/ic_menu_save.png Binary files differnew file mode 100644 index 000000000..36d50b387 --- /dev/null +++ b/samples/NotePad/res/drawable/ic_menu_save.png diff --git a/samples/NotePad/res/drawable-mdpi-v6/live_folder_notes.png b/samples/NotePad/res/drawable/live_folder_notes.png Binary files differindex c565cd0d1..c565cd0d1 100644 --- a/samples/NotePad/res/drawable-mdpi-v6/live_folder_notes.png +++ b/samples/NotePad/res/drawable/live_folder_notes.png diff --git a/samples/NotePad/res/layout/note_editor.xml b/samples/NotePad/res/layout/note_editor.xml index d7da99ee8..552e1051b 100644 --- a/samples/NotePad/res/layout/note_editor.xml +++ b/samples/NotePad/res/layout/note_editor.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2007 The Android Open Source Project +<!-- Copyright (C) 2010 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -13,14 +13,13 @@ See the License for the specific language governing permissions and limitations under the License. --> - <view xmlns:android="http://schemas.android.com/apk/res/android" class="com.example.android.notepad.NoteEditor$LinedEditText" android:id="@+id/note" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/transparent" - android:padding="5dip" + android:padding="5dp" android:scrollbars="vertical" android:fadingEdge="vertical" android:gravity="top" diff --git a/samples/NotePad/res/layout/noteslist_item.xml b/samples/NotePad/res/layout/noteslist_item.xml index e11c5eed2..cafa9b196 100644 --- a/samples/NotePad/res/layout/noteslist_item.xml +++ b/samples/NotePad/res/layout/noteslist_item.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2006 The Android Open Source Project +<!-- Copyright (C) 2010 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/samples/NotePad/res/layout/title_editor.xml b/samples/NotePad/res/layout/title_editor.xml index 3593ec6d7..bbf38fc5b 100644 --- a/samples/NotePad/res/layout/title_editor.xml +++ b/samples/NotePad/res/layout/title_editor.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2007 The Android Open Source Project +<!-- Copyright (C) 2010 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -24,7 +24,8 @@ <EditText android:id="@+id/title" android:maxLines="1" - android:layout_marginTop="2dip" + android:layout_marginTop="2dp" + android:layout_marginBottom="15dp" android:layout_width="wrap_content" android:ems="25" android:layout_height="wrap_content" @@ -36,6 +37,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" - android:text="@string/button_ok" /> + android:text="@string/button_ok" + android:onClick="onClickOk" /> </LinearLayout> diff --git a/samples/NotePad/res/menu/editor_options_menu.xml b/samples/NotePad/res/menu/editor_options_menu.xml new file mode 100644 index 000000000..ce385a645 --- /dev/null +++ b/samples/NotePad/res/menu/editor_options_menu.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:id="@+id/menu_save" + android:icon="@drawable/ic_menu_save" + android:alphabeticShortcut='s' + android:title="@string/menu_save" + android:showAsAction="always" /> + <item android:id="@+id/menu_revert" + android:icon="@drawable/ic_menu_revert" + android:title="@string/menu_revert" /> + <item android:id="@+id/menu_delete" + android:icon="@drawable/ic_menu_delete" + android:title="@string/menu_delete" + android:showAsAction="always" /> +</menu>
\ No newline at end of file diff --git a/samples/NotePad/res/menu/list_context_menu.xml b/samples/NotePad/res/menu/list_context_menu.xml new file mode 100644 index 000000000..71509c63d --- /dev/null +++ b/samples/NotePad/res/menu/list_context_menu.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:id="@+id/context_open" + android:title="@string/menu_open" /> + <item android:id="@+id/context_copy" + android:title="@string/menu_copy" /> + <item android:id="@+id/context_delete" + android:title="@string/menu_delete" /> +</menu>
\ No newline at end of file diff --git a/samples/NotePad/res/menu/list_options_menu.xml b/samples/NotePad/res/menu/list_options_menu.xml new file mode 100644 index 000000000..a60e6a4cc --- /dev/null +++ b/samples/NotePad/res/menu/list_options_menu.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <!-- This is our one standard application action (creating a new note). --> + <item android:id="@+id/menu_add" + android:icon="@drawable/ic_menu_compose" + android:title="@string/menu_add" + android:alphabeticShortcut='a' + android:showAsAction="always" /> + <!-- If there is currently data in the clipboard, this adds a PASTE menu item to the menu + so that the user can paste in the data.. --> + <item android:id="@+id/menu_paste" + android:icon="@drawable/ic_menu_compose" + android:title="@string/menu_paste" + android:alphabeticShortcut='p' /> +</menu>
\ No newline at end of file diff --git a/samples/NotePad/res/values/strings.xml b/samples/NotePad/res/values/strings.xml index 43be4dde7..26d23d072 100644 --- a/samples/NotePad/res/values/strings.xml +++ b/samples/NotePad/res/values/strings.xml @@ -15,27 +15,29 @@ --> <resources> - <string name="menu_copy">Copy</string> + <string name="app_name">NotePad</string> + <string name="live_folder_name">Notes</string> + + <string name="title_edit_title">Note title:</string> + <string name="title_create">New note</string> + <string name="title_edit">Edit: %1$s</string> + <string name="title_notes_list">Notes</string> + + <string name="menu_add">New note</string> + <string name="menu_save">Save</string> <string name="menu_delete">Delete</string> - <string name="menu_insert">Add note</string> + <string name="menu_open">Open</string> + <string name="menu_revert">Revert changes</string> + <string name="menu_copy">Copy</string> <string name="menu_paste">Paste</string> - <string name="menu_revert">Revert</string> - <string name="menu_discard">Discard</string> + + <string name="button_ok">OK</string> + <string name="text_title">Title:</string> <string name="resolve_edit">Edit note</string> - <string name="resolve_title">Edit title</string> + <string name="resolve_title">Edit title</string> - <string name="title_create">Create note</string> - <string name="title_edit">Edit note</string> - <string name="title_notes_list">Note pad</string> - <string name="title_note">Note</string> - <string name="title_edit_title">Note title:</string> - - <string name="app_name">Note Pad</string> - <string name="live_folder_name">Notes</string> - - <string name="button_ok">OK</string> - - <string name="error_title">Error</string> - <string name="error_message">Error loading note</string> -</resources> + <string name="error_title">Error</string> + <string name="error_message">Error loading note</string> + <string name="nothing_to_save">There is nothing to save</string> +</resources>
\ No newline at end of file diff --git a/samples/NotePad/src/com/example/android/notepad/NoteEditor.java b/samples/NotePad/src/com/example/android/notepad/NoteEditor.java index da859745f..a3b8b38f9 100644 --- a/samples/NotePad/src/com/example/android/notepad/NoteEditor.java +++ b/samples/NotePad/src/com/example/android/notepad/NoteEditor.java @@ -16,16 +16,15 @@ package com.example.android.notepad; -import com.example.android.notepad.NotePad; - import android.app.Activity; -import android.content.ClipboardManager; import android.content.ClipData; +import android.content.ClipboardManager; import android.content.ComponentName; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.Intent; +import android.content.res.Resources; import android.database.Cursor; import android.graphics.Canvas; import android.graphics.Paint; @@ -35,6 +34,7 @@ import android.os.Bundle; import android.util.AttributeSet; import android.util.Log; import android.view.Menu; +import android.view.MenuInflater; import android.view.MenuItem; import android.widget.EditText; @@ -51,7 +51,7 @@ import android.widget.EditText; */ public class NoteEditor extends Activity { // For logging and debugging purposes - private static final String TAG = "Notes"; + private static final String TAG = "NoteEditor"; /* * Creates a projection that returns the note ID and the note contents. @@ -62,29 +62,17 @@ public class NoteEditor extends Activity { NotePad.Notes.COLUMN_NAME_TITLE, NotePad.Notes.COLUMN_NAME_NOTE }; - // The index of the note column - private static final int COLUMN_INDEX_NOTE = 1; - - // The index of the title column - private static final int COLUMN_INDEX_TITLE = 2; // A label for the saved state of the activity private static final String ORIGINAL_CONTENT = "origContent"; - // Menu item identifiers - private static final int REVERT_ID = Menu.FIRST; - private static final int DISCARD_ID = Menu.FIRST + 1; - private static final int DELETE_ID = Menu.FIRST + 2; - // This Activity can be started by more than one action. Each action is represented // as a "state" constant private static final int STATE_EDIT = 0; private static final int STATE_INSERT = 1; - private static final int STATE_PASTE = 2; // Global mutable variables private int mState; - private boolean mNoteOnly = false; private Uri mUri; private Cursor mCursor; private EditText mText; @@ -199,15 +187,6 @@ public class NoteEditor extends Activity { // set the result to be returned. setResult(RESULT_OK, (new Intent()).setAction(mUri.toString())); - // For a paste, initializes the data from clipboard. - if (Intent.ACTION_PASTE.equals(action)) { - - // Does the paste - performPaste(); - // Switches the state to PASTE. The title can not be modified. - mState = STATE_PASTE; - } - // If the action was other than EDIT or INSERT: } else { @@ -218,12 +197,6 @@ public class NoteEditor extends Activity { return; } - // Sets the layout for this Activity. See res/layout/note_editor.xml - setContentView(R.layout.note_editor); - - // Gets a handle to the EditText in the the layout. - mText = (EditText) findViewById(R.id.note); - /* * Using the URI passed in with the triggering Intent, gets the note or notes in * the provider. @@ -240,6 +213,21 @@ public class NoteEditor extends Activity { null // Use the default sort order (modification date, descending) ); + // For a paste, initializes the data from clipboard. + // (Must be done after mCursor is initialized.) + if (Intent.ACTION_PASTE.equals(action)) { + // Does the paste + performPaste(); + // Switches the state to EDIT so the title can be modified. + mState = STATE_EDIT; + } + + // Sets the layout for this Activity. See res/layout/note_editor.xml + setContentView(R.layout.note_editor); + + // Gets a handle to the EditText in the the layout. + mText = (EditText) findViewById(R.id.note); + /* * If this Activity had stopped previously, its state was written the ORIGINAL_CONTENT * location in the saved Instance state. This gets the state. @@ -266,6 +254,8 @@ public class NoteEditor extends Activity { * process. This tests that it's not null, since it should always contain data. */ if (mCursor != null) { + // Requery in case something changed while paused (such as the title) + mCursor.requery(); /* Moves to the first record. Always call moveToFirst() before accessing data in * a Cursor for the first time. The semantics of using a Cursor are that when it is @@ -276,12 +266,14 @@ public class NoteEditor extends Activity { // Modifies the window title for the Activity according to the current Activity state. if (mState == STATE_EDIT) { - - // Sets the title to Edit for edits - setTitle(getText(R.string.title_edit)); - - // Sets the title to "create" for inserts and pastes - } else if (mState == STATE_INSERT || mState == STATE_PASTE) { + // Set the title of the Activity to include the note title + int colTitleIndex = mCursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_TITLE); + String title = mCursor.getString(colTitleIndex); + Resources res = getResources(); + String text = String.format(res.getString(R.string.title_edit), title); + setTitle(text); + // Sets the title to "create" for inserts + } else if (mState == STATE_INSERT) { setTitle(getText(R.string.title_create)); } @@ -294,7 +286,8 @@ public class NoteEditor extends Activity { // Gets the note text from the Cursor and puts it in the TextView, but doesn't change // the text cursor's position. - String note = mCursor.getString(COLUMN_INDEX_NOTE); + int colNoteIndex = mCursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_NOTE); + String note = mCursor.getString(colNoteIndex); mText.setTextKeepState(note); // Stores the original note text, to allow the user to revert changes. @@ -361,7 +354,7 @@ public class NoteEditor extends Activity { * even if the note was being edited, the assumption being that the user wanted to * "clear out" (delete) the note. */ - if (isFinishing() && (length == 0) && !mNoteOnly) { + if (isFinishing() && (length == 0)) { setResult(RESULT_CANCELED); deleteNote(); @@ -371,11 +364,13 @@ public class NoteEditor extends Activity { * onCreate() inserted a new empty note into the provider, and it is this new note * that is being edited. */ - } else { - + } else if (mState == STATE_EDIT) { // Creates a map to contain the new values for the columns - updateNote(text, null, !mNoteOnly); - } + updateNote(text, null); + } else if (mState == STATE_INSERT) { + updateNote(text, text); + mState = STATE_EDIT; + } } } @@ -391,72 +386,38 @@ public class NoteEditor extends Activity { */ @Override public boolean onCreateOptionsMenu(Menu menu) { - super.onCreateOptionsMenu(menu); + // Inflate menu from XML resource + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.editor_options_menu, menu); - // Builds the menus that are shown when editing. These are 'revert' to undo changes, and - // 'delete' to delete the note. + // Only add extra menu items for a saved note if (mState == STATE_EDIT) { - - // Adds the 'revert' menu item, and sets its shortcut to numeric 0, letter 'r' and its - // icon to the Android standard revert icon. - menu.add(0, REVERT_ID, 0, R.string.menu_revert) - .setShortcut('0', 'r') - .setIcon(android.R.drawable.ic_menu_revert); - if (!mNoteOnly) { - - // Adds the 'delete' menu item, and sets its shortcut to numeric 1, letter 'd' - // and its icon to the Android standard delete icon - menu.add(0, DELETE_ID, 0, R.string.menu_delete) - .setShortcut('1', 'd') - .setIcon(android.R.drawable.ic_menu_delete); - } - - // Builds the menus that are shown when inserting. The only option is 'Discard' to throw - // away the new note. - } else { - menu.add(0, DISCARD_ID, 0, R.string.menu_discard) - .setShortcut('0', 'd') - .setIcon(android.R.drawable.ic_menu_delete); - } - - /* - * Appends menu items for any Activity declarations that implement an alternative action - * for this Activity's MIME type, one menu item for each Activity. - */ - if (!mNoteOnly) { - - // Makes a new Intent with the URI data passed to this Activity - Intent intent = new Intent(null, getIntent().getData()); - - // Adds the ALTERNATIVE category to the Intent. + // Append to the + // menu items for any other activities that can do stuff with it + // as well. This does a query on the system for any activities that + // implement the ALTERNATIVE_ACTION for our data, adding a menu item + // for each one that is found. + Intent intent = new Intent(null, mUri); intent.addCategory(Intent.CATEGORY_ALTERNATIVE); + menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0, + new ComponentName(this, NoteEditor.class), null, intent, 0, null); + } - /* - * Constructs a new ComponentName object that represents the current Activity. - */ - ComponentName component = new ComponentName( - this, - NoteEditor.class); + return super.onCreateOptionsMenu(menu); + } - /* - * In the ALTERNATIVE menu group, adds an option for each Activity that is registered to - * handle this Activity's MIME type. The Intent describes what type of items should be - * added to the menu; in this case, Activity declarations with category ALTERNATIVE. - */ - menu.addIntentOptions( - Menu.CATEGORY_ALTERNATIVE, // The menu group to add the items to. - Menu.NONE, // No unique ID is needed. - Menu.NONE, // No ordering is needed. - component, // The current Activity object's component name - null, // No specific items need to be placed first. - intent, // The intent containing the type of items to add. - Menu.NONE, // No flags are necessary. - null // No need to generate an array of menu items. - ); + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + // Check if note has changed and enable/disable the revert option + int colNoteIndex = mCursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_NOTE); + String savedNote = mCursor.getString(colNoteIndex); + String currentNote = mText.getText().toString(); + if (savedNote.equals(currentNote)) { + menu.findItem(R.id.menu_revert).setVisible(false); + } else { + menu.findItem(R.id.menu_revert).setVisible(true); } - - // The method returns TRUE, so that further menu processing is not done. - return true; + return super.onPrepareOptionsMenu(menu); } /** @@ -470,29 +431,21 @@ public class NoteEditor extends Activity { */ @Override public boolean onOptionsItemSelected(MenuItem item) { - - // Chooses the action to perform + // Handle all of the possible menu actions. switch (item.getItemId()) { - - // Deletes the note and close the Activity. - case DELETE_ID: - deleteNote(); - finish(); - break; - - // Discards the new note. - case DISCARD_ID: - cancelNote(); - break; - - // Discards any changes to an edited note. - case REVERT_ID: - cancelNote(); - break; + case R.id.menu_save: + String text = mText.getText().toString(); + updateNote(text, null); + finish(); + break; + case R.id.menu_delete: + deleteNote(); + finish(); + break; + case R.id.menu_revert: + cancelNote(); + break; } - - // Continues with processing the menu item. In effect, if the item was an alternative - // action, this invokes the Activity for that action. return super.onOptionsItemSelected(item); } @@ -540,8 +493,10 @@ public class NoteEditor extends Activity { // (moveToFirst() returns true), then this gets the note data from it. if (orig != null) { if (orig.moveToFirst()) { - text = orig.getString(COLUMN_INDEX_NOTE); - title = orig.getString(COLUMN_INDEX_TITLE); + int colNoteIndex = mCursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_NOTE); + int colTitleIndex = mCursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_TITLE); + text = orig.getString(colNoteIndex); + title = orig.getString(colTitleIndex); } // Closes the cursor. @@ -556,7 +511,7 @@ public class NoteEditor extends Activity { } // Updates the current note with the retrieved title and text. - updateNote(text, title, true); + updateNote(text, title); } } //END_INCLUDE(paste) @@ -565,44 +520,40 @@ public class NoteEditor extends Activity { * Replaces the current note contents with the text and title provided as arguments. * @param text The new note contents to use. * @param title The new note title to use - * @param updateTitle <em>true</em> if the title should be updated. This also updates the - * modification timestamp to the current time. */ - private final void updateNote(String text, String title, boolean updateTitle) { + private final void updateNote(String text, String title) { // Sets up a map to contain values to be updated in the provider. ContentValues values = new ContentValues(); - - // If updateTitle is true, sets the modification date/time stamp to now. - if (updateTitle) { - values.put(NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE, System.currentTimeMillis()); - - // If the action is to insert a new note, this creates an initial title for it. - if (mState == STATE_INSERT) { - - // If no title was provided as an argument, create one from the note text. - if (title == null) { - - // Get the note's length - int length = text.length(); - - // Sets the title by getting a substring of the text that is 31 characters long - // or the number of characters in the note plus one, whichever is smaller. - title = text.substring(0, Math.min(30, length)); - - // If the resulting length is more than 30 characters, chops off any - // trailing spaces - if (length > 30) { - int lastSpace = title.lastIndexOf(' '); - if (lastSpace > 0) { - title = title.substring(0, lastSpace); - } + values.put(NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE, System.currentTimeMillis()); + + // If the action is to insert a new note, this creates an initial title for it. + if (mState == STATE_INSERT) { + + // If no title was provided as an argument, create one from the note text. + if (title == null) { + + // Get the note's length + int length = text.length(); + + // Sets the title by getting a substring of the text that is 31 characters long + // or the number of characters in the note plus one, whichever is smaller. + title = text.substring(0, Math.min(30, length)); + + // If the resulting length is more than 30 characters, chops off any + // trailing spaces + if (length > 30) { + int lastSpace = title.lastIndexOf(' '); + if (lastSpace > 0) { + title = title.substring(0, lastSpace); } } - - // In the values map, sets the value of the title - values.put(NotePad.Notes.COLUMN_NAME_TITLE, title); } + // In the values map, sets the value of the title + values.put(NotePad.Notes.COLUMN_NAME_TITLE, title); + } else if (title != null) { + // In the values map, sets the value of the title + values.put(NotePad.Notes.COLUMN_NAME_TITLE, title); } // This puts the desired notes text into the map. @@ -634,8 +585,6 @@ public class NoteEditor extends Activity { * newly created, or reverts to the original text of the note i */ private final void cancelNote() { - - // If if (mCursor != null) { if (mState == STATE_EDIT) { // Put the original note text back into the database diff --git a/samples/NotePad/src/com/example/android/notepad/NotesList.java b/samples/NotePad/src/com/example/android/notepad/NotesList.java index 6229dd257..8f0b2cb02 100644 --- a/samples/NotePad/src/com/example/android/notepad/NotesList.java +++ b/samples/NotePad/src/com/example/android/notepad/NotesList.java @@ -31,6 +31,7 @@ import android.os.Bundle; import android.util.Log; import android.view.ContextMenu; import android.view.Menu; +import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ContextMenu.ContextMenuInfo; @@ -53,12 +54,6 @@ public class NotesList extends ListActivity { // For logging and debugging private static final String TAG = "NotesList"; - // Menu item ids - public static final int MENU_ITEM_DELETE = Menu.FIRST; - public static final int MENU_ITEM_COPY = Menu.FIRST + 1; - public static final int MENU_ITEM_INSERT = Menu.FIRST + 2; - public static final int MENU_ITEM_PASTE = Menu.FIRST + 3; - /** * The columns needed by the cursor adapter */ @@ -70,8 +65,6 @@ public class NotesList extends ListActivity { /** The index of the title column */ private static final int COLUMN_INDEX_TITLE = 1; - private MenuItem mPasteItem; - /** * onCreate is called when Android starts this Activity from scratch. */ @@ -159,70 +152,20 @@ public class NotesList extends ListActivity { */ @Override public boolean onCreateOptionsMenu(Menu menu) { + // Inflate menu from XML resource + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.list_options_menu, menu); - // The parent method creates the default method with the standard system items. - super.onCreateOptionsMenu(menu); - - // Adds an Insert menu item - MenuItem menuItem = menu.add( - Menu.NONE, // No menu group. - MENU_ITEM_INSERT, // Unique ID for this item. - Menu.NONE, // No order within the group. - R.string.menu_insert // Displayed text for the menu item. - ); - - // Sets keyboard shortcuts for the menu item, either "3" or "a"; - menuItem.setShortcut('3', 'a'); - - // Sets the icon for the menu item - menuItem.setIcon(android.R.drawable.ic_menu_add); - - // If there is currently data in the clipboard, this adds a PASTE menu item to the menu - // so that the user can paste in the data. - mPasteItem = menu.add( - Menu.NONE, // No menu group. - MENU_ITEM_PASTE, // A unique ID for this item - Menu.NONE, // No menu order - R.string.menu_paste // The displayed text - ).setShortcut('4', 'p'); // Set the keyboard shortcuts for this new item. - - // Generates any additional actions that can be performed on the + // Generate any additional actions that can be performed on the // overall list. In a normal install, there are no additional // actions found here, but this allows other applications to extend // our menu with their own actions. - - /* Creates a new Intent with the same incoming data and no defined action. - * It also sets its category to ALTERNATIVE. This prepares the Intent as a place - * to group alternative options in the menu. - */ Intent intent = new Intent(null, getIntent().getData()); intent.addCategory(Intent.CATEGORY_ALTERNATIVE); + menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0, + new ComponentName(this, NotesList.class), null, intent, 0, null); - /* Creates a ComponentName from the current Context and this Activity object's - * class object. - */ - ComponentName component = new ComponentName(this, NotesList.class); - - /* - * Adds any other activities that want to be alternatives for this view. In effect, - * any application can add itself as an alternative on the options menu. - */ - menu.addIntentOptions( - Menu.CATEGORY_ALTERNATIVE, // Add the options to the Alternatives group - Menu.NONE, // Do not use a unique ID - Menu.NONE, // No need to order the options - component, // The ComponentName of the Activity making the request. - // This Activity is excluded from the list of alternatives. - null, // No specific items are listed first. - intent, // The Intent to resolve to, in effect, an Intent listing - // the alternatives - Menu.NONE, // no flags are needed - null // Since no specifics were used, so a menu item array is - // not needed. - ); - - // Returns true so that the menu is displayed. - return true; + return super.onCreateOptionsMenu(menu); } @Override @@ -233,11 +176,13 @@ public class NotesList extends ListActivity { ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); + + MenuItem mPasteItem = menu.findItem(R.id.menu_paste); + // If the clipboard contains an item, enables the Paste option on the menu. if (clipboard.hasPrimaryClip()) { mPasteItem.setEnabled(true); } else { - // If the clipboard is empty, disables the menu's Paste option. mPasteItem.setEnabled(false); } @@ -274,7 +219,6 @@ public class NotesList extends ListActivity { */ intent.addCategory(Intent.CATEGORY_ALTERNATIVE); - /* * Add alternatives to the menu */ @@ -318,36 +262,26 @@ public class NotesList extends ListActivity { */ @Override public boolean onOptionsItemSelected(MenuItem item) { - - // Gets the ID of the selected item switch (item.getItemId()) { - - // If the menu item is Insert - case MENU_ITEM_INSERT: - - /* - * Launches a new Activity using an Intent. The intent filter for the Activity - * has to have action ACTION_INSERT. No category is set, so DEFAULT is assumed. - * In effect, this starts the NoteEditor Activity in NotePad. - */ - startActivity(new Intent(Intent.ACTION_INSERT, getIntent().getData())); - return true; - - // If the menu item is Paste - case MENU_ITEM_PASTE: - - /* - * Launches a new Activity using an Intent. The intent filter for the Activity - * has to have action ACTION_PASTE. No category is set, so DEFAULT is assumed. - * In effect, this starts the NoteEditor Activity in NotePad. - */ - startActivity(new Intent(Intent.ACTION_PASTE, getIntent().getData())); - return true; + case R.id.menu_add: + /* + * Launches a new Activity using an Intent. The intent filter for the Activity + * has to have action ACTION_INSERT. No category is set, so DEFAULT is assumed. + * In effect, this starts the NoteEditor Activity in NotePad. + */ + startActivity(new Intent(Intent.ACTION_INSERT, getIntent().getData())); + return true; + case R.id.menu_paste: + /* + * Launches a new Activity using an Intent. The intent filter for the Activity + * has to have action ACTION_PASTE. No category is set, so DEFAULT is assumed. + * In effect, this starts the NoteEditor Activity in NotePad. + */ + startActivity(new Intent(Intent.ACTION_PASTE, getIntent().getData())); + return true; + default: + return super.onOptionsItemSelected(item); } - - // If the menu item selected is not Insert or Paste, then this calls the regular - // processing to handle the item. - return super.onOptionsItemSelected(item); } /** @@ -371,11 +305,9 @@ public class NotesList extends ListActivity { // Tries to get the position of the item in the ListView that was long-pressed. try { - // Casts the incoming data object into the type for AdapterView objects. info = (AdapterView.AdapterContextMenuInfo) menuInfo; } catch (ClassCastException e) { - // If the menu object can't be cast, logs an error. Log.e(TAG, "bad menuInfo", e); return; @@ -392,29 +324,27 @@ public class NotesList extends ListActivity { // If the cursor is empty, then for some reason the adapter can't get the data from the // provider, so returns null to the caller. if (cursor == null) { - // For some reason the requested item isn't available, do nothing return; } + // Inflate menu from XML resource + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.list_context_menu, menu); + // Sets the menu header to be the title of the selected note. menu.setHeaderTitle(cursor.getString(COLUMN_INDEX_TITLE)); - // Adds a menu item to copy the note to the context menu - menu.add( - Menu.NONE, // No grouping is needed for this menu - MENU_ITEM_COPY, // A unique ID for this menu item. - Menu.NONE, // No ordering is necessary in this menu - R.string.menu_copy // The resource ID for the string to display for this item. - ); - - // Adds a menu item to delete the note to the context menu - menu.add( - Menu.NONE, // No grouping is needed for this menu - MENU_ITEM_DELETE, // A unique ID for this menu item. - Menu.NONE, // No ordering is necessary in this menu - R.string.menu_delete // The resource ID for the string to display for this item. - ); + // Append to the + // menu items for any other activities that can do stuff with it + // as well. This does a query on the system for any activities that + // implement the ALTERNATIVE_ACTION for our data, adding a menu item + // for each one that is found. + Intent intent = new Intent(null, Uri.withAppendedPath(getIntent().getData(), + Integer.toString((int) info.id) )); + intent.addCategory(Intent.CATEGORY_ALTERNATIVE); + menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0, + new ComponentName(this, NotesList.class), null, intent, 0, null); } /** @@ -429,7 +359,6 @@ public class NotesList extends ListActivity { */ @Override public boolean onContextItemSelected(MenuItem item) { - // The data from the menu item. AdapterView.AdapterContextMenuInfo info; @@ -446,7 +375,6 @@ public class NotesList extends ListActivity { * note ID, to onContextItemSelected() via the item parameter. */ try { - // Casts the data object in the item into the type for AdapterView objects. info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); } catch (ClassCastException e) { @@ -457,58 +385,51 @@ public class NotesList extends ListActivity { // Triggers default processing of the menu item. return false; } + // Appends the selected note's ID to the URI sent with the incoming Intent. + Uri noteUri = ContentUris.withAppendedId(getIntent().getData(), info.id); /* - * Gets the menu item's ID and compares it to known actions. The only actions that are - * implemented are COPY and DELETE (set in onCreateContextMenu()). + * Gets the menu item's ID and compares it to known actions. */ switch (item.getItemId()) { - - // Deletes the selected note - case MENU_ITEM_DELETE: { - - // Appends the selected note's ID to the URI sent with the incoming Intent. - Uri noteUri = ContentUris.withAppendedId(getIntent().getData(), info.id); - - // Deletes the note from the provider by passing in a URI in note ID format. - // Please see the introductory note about performing provider operations on the - // UI thread. - getContentResolver().delete( - noteUri, // The URI of the provider - null, // No where clause is needed, since only a single note ID is being - // passed in. - null // No where clause is used, so no where arguments are needed. - ); - - // Returns to the caller and skips further processing. - return true; - } - + case R.id.context_open: + // Launch activity to view/edit the currently selected item + startActivity(new Intent(Intent.ACTION_EDIT, noteUri)); + return true; //BEGIN_INCLUDE(copy) - // Copies the selected note to the clipboard - case MENU_ITEM_COPY: { - - // Gets a handle to the clipboard service. - ClipboardManager clipboard = (ClipboardManager) - getSystemService(Context.CLIPBOARD_SERVICE); - - // Appends the selected note's ID to the URI sent with the incoming Intent. - Uri noteUri = ContentUris.withAppendedId(getIntent().getData(), info.id); - - // Copies the notes URI to the clipboard. In effect, this copies the note itself - clipboard.setPrimaryClip(ClipData.newUri( // new clipboard item holding a URI - getContentResolver(), // resolver to retrieve URI info - "Note", // label for the clip - null, // icon for the clip - noteUri) // the URI - ); - - // Returns to the caller and skips further processing. - return true; - } + case R.id.context_copy: + // Gets a handle to the clipboard service. + ClipboardManager clipboard = (ClipboardManager) + getSystemService(Context.CLIPBOARD_SERVICE); + + // Copies the notes URI to the clipboard. In effect, this copies the note itself + clipboard.setPrimaryClip(ClipData.newUri( // new clipboard item holding a URI + getContentResolver(), // resolver to retrieve URI info + "Note", // label for the clip + null, // icon for the clip + noteUri) // the URI + ); + + // Returns to the caller and skips further processing. + return true; //END_INCLUDE(copy) + case R.id.context_delete: + + // Deletes the note from the provider by passing in a URI in note ID format. + // Please see the introductory note about performing provider operations on the + // UI thread. + getContentResolver().delete( + noteUri, // The URI of the provider + null, // No where clause is needed, since only a single note ID is being + // passed in. + null // No where clause is used, so no where arguments are needed. + ); + + // Returns to the caller and skips further processing. + return true; + default: + return super.onContextItemSelected(item); } - return false; } /** diff --git a/samples/NotePad/src/com/example/android/notepad/TitleEditor.java b/samples/NotePad/src/com/example/android/notepad/TitleEditor.java index b41a35cc7..5abe97b39 100644 --- a/samples/NotePad/src/com/example/android/notepad/TitleEditor.java +++ b/samples/NotePad/src/com/example/android/notepad/TitleEditor.java @@ -16,15 +16,12 @@ package com.example.android.notepad; -import com.example.android.notepad.NotePad; - import android.app.Activity; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.view.View; -import android.widget.Button; import android.widget.EditText; /** @@ -36,7 +33,7 @@ import android.widget.EditText; * application should use the {@link android.content.AsyncQueryHandler} * or {@link android.os.AsyncTask} object to perform operations asynchronously on a separate thread. */ -public class TitleEditor extends Activity implements View.OnClickListener { +public class TitleEditor extends Activity { /** * This is a special intent action that means "edit the title of a note". @@ -95,11 +92,6 @@ public class TitleEditor extends Activity implements View.OnClickListener { // Gets the View ID for the EditText box mText = (EditText) this.findViewById(R.id.title); - - // Sets up a listener for the OK button. Gets the Button by its ID, then sets its - // onClickListener to this Activity. - Button b = (Button) findViewById(R.id.ok); - b.setOnClickListener(this); } /** @@ -169,16 +161,7 @@ public class TitleEditor extends Activity implements View.OnClickListener { } } - /** - * This method is called when the user clicks anywhere in the title text box. - * - * It calls finish(), which immediately triggers the onPause() method in this Activity. In - * turn, onPause() saves the text currently in the title text box to the note. - */ - public void onClick(View v) { - - // Calls finish to force the Activity to shut down. In the lifecycle, this forces a call to - // onPause(), which saves the work the user has done. + public void onClickOk(View v) { finish(); } } |
