diff options
Diffstat (limited to 'docs/html/guide/tutorials/notepad/notepad-ex2.jd')
-rw-r--r-- | docs/html/guide/tutorials/notepad/notepad-ex2.jd | 150 |
1 files changed, 72 insertions, 78 deletions
diff --git a/docs/html/guide/tutorials/notepad/notepad-ex2.jd b/docs/html/guide/tutorials/notepad/notepad-ex2.jd index 3b8fa0b..a945a62 100644 --- a/docs/html/guide/tutorials/notepad/notepad-ex2.jd +++ b/docs/html/guide/tutorials/notepad/notepad-ex2.jd @@ -1,11 +1,11 @@ -page.title=Notepad Exercise 2 +Rpage.title=Notepad Exercise 2 parent.title=Notepad Tutorial parent.link=index.html @jd:body <p><em>In this exercise, you will add a second Activity to your notepad application, to let the user -create and edit notes. You will also allow the user to delete existing notes through a context menu. +create and edit notes. You will also allow the user to delete existing notes through a context menu. The new Activity assumes responsibility for creating new notes by collecting user input and packing it into a return Bundle provided by the intent. This exercise demonstrates:</em></p> @@ -55,7 +55,7 @@ Tools</strong> > <strong>Fix Project Properties</strong>.</p> </li> <li> There are also a couple of new overridden methods - (<code>onCreateContextMenu()</code>, <code>onContextItemSelected()</code>, + (<code>onCreateContextMenu()</code>, <code>onContextItemSelected()</code>, <code>onListItemClick()</code> and <code>onActivityResult()</code>) which we will be filling in below. </li> @@ -63,19 +63,20 @@ Tools</strong> > <strong>Fix Project Properties</strong>.</p> <h2>Step 2</h2> - +<div class="sidebox-wrapper"> <div class="sidebox"> <p>Context menus should always be used when performing actions upon specific elements in the UI. When you register a View to a context menu, the context menu is revealed by performing a "long-click" on the UI component (press and hold the touchscreen or highlight and hold down the selection key for about two seconds).</p> </div> +</div> <p>First, let's create the context menu that will allow users to delete individual notes. Open the Notepadv2 class.</p> <ol> <li>In order for each list item in the ListView to register for the context menu, we call - <code>registerForContextMenu()</code> and pass it our ListView. So, at the very end of + <code>registerForContextMenu()</code> and pass it our ListView. So, at the very end of the <code>onCreate()</code> method add this line: <pre>registerForContextMenu(getListView());</pre> <p>Because our Activity extends the ListActivity class, <code>getListView()</code> will return us @@ -91,7 +92,7 @@ public boolean onCreateContextMenu(Menu menu, View v super.onCreateContextMenu(menu, v, menuInfo); menu.add(0, DELETE_ID, 0, R.string.menu_delete); }</pre> - <p>The <code>onCreateContextMenu()</code> callback some passes other information in addition to the Menu object, + <p>The <code>onCreateContextMenu()</code> callback passes some other information in addition to the Menu object, such as the View that has been triggered for the menu and an extra object that may contain additional information about the object selected. However, we don't care about these here, because we only have one kind of object in the Activity that uses context menus. In the next @@ -102,7 +103,7 @@ public boolean onCreateContextMenu(Menu menu, View v <h2>Step 3</h2> <p>Now that the we've registered our ListView for a context menu and defined our context menu item, we need to handle the callback when it is selected. For this, we need to identify the list ID of the - selected item, then delete it. So fill in the + selected item, then delete it. So fill in the <code>onContextItemSelected()</code> method like this:</p> <pre> public boolean onContextItemSelected(MenuItem item) { @@ -122,26 +123,23 @@ method of our NotesDbAdapter and the note is deleted. That's it for the context can now be deleted.</p> <h2 style="clear:right;">Step 4</h2> -<div class="sidebox" style="border:2px solid #FFFFDD;float:right; - background-color:#FFFFEE;margin-right:0px; - margin-bottom:.5em;margin-top:1em;padding:0em;width:240px;"> - <h2 style="border:0;font-size:12px;padding:.5em .5em .5em 1em;margin:0; - background-color:#FFFFDD;">Starting Other Activities</h2> - <p style="padding-left:.5em;font-size:12px;margin:0; - padding:.0em .5em .5em 1em;">In this example our Intent uses a class name specifically. - As well as - <a href="{@docRoot}guide/appendix/faq/commontasks.html#intentexamples">starting intents</a> in - classes we already know about, be they in our own application or another - application, we can also create Intents without knowing exactly which + <div class="sidebox-wrapper"> + <div class="sidebox"> + <h2>Starting Other Activities</h2> + <p>In this example our Intent uses a class name specifically. + As well as + <a href="{@docRoot}resources/faq/commontasks.html#intentexamples">starting intents</a> in + classes we already know about, be they in our own application or another + application, we can also create Intents without knowing exactly which application will handle it.</p> - <p style="padding-left:.5em;font-size:12px;margin:0; - padding:.0em .5em .5em 1em;">For example, we might want to open a page in a + <p>For example, we might want to open a page in a browser, and for this we still use an Intent. But instead of specifying a class to handle it, we use a predefined Intent constant, and a content URI that describes what we want to do. See {@link android.content.Intent android.content.Intent} for more information.</p> -</div> + </div> + </div> <p>Fill in the body of the <code>createNote()</code> method: <p>Create a new <code>Intent</code> to create a note @@ -155,7 +153,7 @@ startActivityForResult(i, ACTIVITY_CREATE);</pre> <code>NoteEdit</code>. Since the Intent class will need to communicate with the Android operating system to route requests, we also have to provide a Context (<code>this</code>).</p> <p>The <code>startActivityForResult()</code> method fires the Intent in a way that causes a method - in our Activity to be called when the new Activity is completed. The method in our Activity + in our Activity to be called when the new Activity is completed. The method in our Activity that receives the callback is called <code>onActivityResult()</code> and we will implement it in a later step. The other way to call an Activity is using <code>startActivity()</code> but this is a "fire-and-forget" way @@ -164,7 +162,7 @@ startActivityForResult(i, ACTIVITY_CREATE);</pre> <p>Don't worry about the fact that <code>NoteEdit</code> doesn't exist yet, we will fix that soon. </p> </li> - + <h2>Step 5</h2> @@ -180,7 +178,7 @@ startActivityForResult(i, ACTIVITY_CREATE);</pre> interested in is the <code>position</code> that the user selected. We use this to get the data from the correct row, and bundle it up to send to the <code>NoteEdit</code> Activity.</p> - <p>In our implementation of the callback, the method creates an + <p>In our implementation of the callback, the method creates an <code>Intent</code> to edit the note using the <code>NoteEdit</code> class. It then adds data into the extras Bundle of the Intent, which will be passed to the called Activity. We use it @@ -207,7 +205,7 @@ startActivityForResult(i, ACTIVITY_EDIT);</pre> </li> <li> The details of the note are pulled out from our query Cursor, which we move to the - proper position for the element that was selected in the list, with + proper position for the element that was selected in the list, with the <code>moveToPosition()</code> method.</li> <li>With the extras added to the Intent, we invoke the Intent on the <code>NoteEdit</code> class by passing <code>startActivityForResult()</code> @@ -219,7 +217,7 @@ startActivityForResult(i, ACTIVITY_EDIT);</pre> variable is much more efficient than accessing a field in the Dalvik VM, so by doing this we make only one access to the field, and five accesses to the local variable, making the routine much more efficient. It is recommended that you use this optimization when possible.</p> - + <h2>Step 6</h2> @@ -243,7 +241,7 @@ startActivityForResult(i, ACTIVITY_EDIT);</pre> <li><code>intent</code> — this is an Intent created by the Activity returning results. It can be used to return data in the Intent "extras." </li> - </ul> + </ul> <p>The combination of <code>startActivityForResult()</code> and <code>onActivityResult()</code> can be thought of as an asynchronous RPC (remote procedure call) and forms the recommended way for an Activity to invoke @@ -277,7 +275,7 @@ case ACTIVITY_EDIT: <code>ACTIVITY_EDIT</code> activity results in this method. </li> <li> - In the case of a create, we pull the title and body from the extras (retrieved from the + In the case of a create, we pull the title and body from the extras (retrieved from the returned Intent) and use them to create a new note. </li> <li> @@ -288,29 +286,27 @@ case ACTIVITY_EDIT: <code>fillData()</code> at the end ensures everything is up to date . </li> </ul> - + <h2>Step 7</h2> - <div class="sidebox" style="border:2px solid #FFFFDD;float:right; - background-color:#FFFFEE;margin-right:0px; - margin-bottom:.5em;margin-top:1em;padding:0em;width:240px;"> - <h2 style="border:0;font-size:12px;padding:.5em .5em .5em 1em;margin:0; - background-color:#FFFFDD;">The Art of Layout</h2> - <p style="padding-left:.5em;font-size:12px;margin:0; padding:.0em .5em .5em 1em;">The provided + <div class="sidebox-wrapper"> + <div class="sidebox"> + <h2>The Art of Layout</h2> + <p>The provided note_edit.xml layout file is the most sophisticated one in the application we will be building, but that doesn't mean it is even close to the kind of sophistication you will be likely to want in real Android applications.</p> - <p style="padding-left:.5em;font-size:12px;margin:0; padding:.0em .5em .5em 1em;">Creating a + <p>Creating a good UI is part art and part science, and the rest is work. Mastery of <a href="{@docRoot}guide/topics/ui/declaring-layout.html">Declaring Layout</a> is an essential part of creating a good looking Android application.</p> - <p style="padding-left:.5em;font-size:12px;margin:0; - padding:.0em .5em .5em 1em;">Take a look at the - <a href="{@docRoot}guide/tutorials/views/index.html">Hello Views</a> + <p>Take a look at the + <a href="{@docRoot}resources/tutorials/views/index.html">Hello Views</a> for some example layouts and how to use them. The ApiDemos sample project is also a great resource from which to learn how to create different layouts.</p> </div> + </div> <p>Open the file <code>note_edit.xml</code> that has been provided and take a look at it. This is the UI code for the Note Editor.</p> @@ -335,7 +331,7 @@ case ACTIVITY_EDIT: <code>layout_weight</code> specified, so it takes up the minimum space required to render. If the <code>layout_weight</code> of each of the two text edit elements is set to 1, the remaining width in the parent layout will - be split equally between them (because we claim they are equally important). + be split equally between them (because we claim they are equally important). If the first one has a <code>layout_weight</code> of 1 and the second has a <code>layout_weight</code> of 2, then one third of the remaining space will be given to the first, and two thirds to the @@ -373,7 +369,7 @@ case ACTIVITY_EDIT: <code>onCreate(Bundle)</code> — and check the box next to it.</li> <li>Click <strong>OK</strong>.<p>The method should now appear in your class.</p></li> </ol> - + <h2>Step 9</h2> <p>Fill in the body of the <code>onCreate()</code> method for <code>NoteEdit</code>.</p> @@ -388,7 +384,7 @@ case ACTIVITY_EDIT: <p>We can then unbundle the values that were passed in to the Activity with the extras Bundle attached to the calling Intent. We'll use them to pre-populate the title and body text edit views so that the user can edit them. - Then we will grab and store the <code>mRowId</code> so we can keep + Then we will grab and store the <code>mRowId</code> so we can keep track of what note the user is editing.</p> <ol> @@ -406,14 +402,14 @@ case ACTIVITY_EDIT: mTitleText = (EditText) findViewById(R.id.title); mBodyText = (EditText) findViewById(R.id.body); Button confirmButton = (Button) findViewById(R.id.confirm);</pre> - <p>Note that <code>mTitleText</code> and <code>mBodyText</code> are member + <p>Note that <code>mTitleText</code> and <code>mBodyText</code> are member fields (you need to declare them at the top of the class definition).</p> </li> <li>At the top of the class, declare a <code>Long mRowId</code> private field to store the current <code>mRowId</code> being edited (if any). </li> - <li>Continuing inside <code>onCreate()</code>, - add code to initialize the <code>title</code>, <code>body</code> and + <li>Continuing inside <code>onCreate()</code>, + add code to initialize the <code>title</code>, <code>body</code> and <code>mRowId</code> from the extras Bundle in the Intent (if it is present):<br> <pre> @@ -423,7 +419,7 @@ 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); } @@ -459,16 +455,16 @@ if (extras != null) { confirmButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { - + } - + });</pre> </li> </ol> <h2>Step 10</h2> <p>Fill in the body of the <code>onClick()</code> method of the <code>OnClickListener</code> created in the last step.</p> - + <p>This is the code that will be run when the user clicks on the confirm button. We want this to grab the title and body text from the edit text fields, and put them into the return Bundle so that they can be passed @@ -483,7 +479,7 @@ confirmButton.setOnClickListener(new View.OnClickListener() { constants defined in Notepadv2 as keys:<br> <pre> Bundle bundle = new Bundle(); - + bundle.putString(NotesDbAdapter.KEY_TITLE, mTitleText.getText().toString()); bundle.putString(NotesDbAdapter.KEY_BODY, mBodyText.getText().toString()); if (mRowId != null) { @@ -498,7 +494,7 @@ mIntent.putExtras(bundle); setResult(RESULT_OK, mIntent); finish();</pre> <ul> - <li>The Intent is simply our data carrier that carries our Bundle + <li>The Intent is simply our data carrier that carries our Bundle (with the title, body and mRowId).</li> <li>The <code>setResult()</code> method is used to set the result code and return Intent to be passed back to the @@ -521,19 +517,19 @@ private Long mRowId; protected void onCreate(Bundle savedInstanceState) { 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); - + 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); } @@ -541,12 +537,12 @@ protected void onCreate(Bundle savedInstanceState) { mBodyText.setText(body); } } - + confirmButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { Bundle bundle = new Bundle(); - + bundle.putString(NotesDbAdapter.KEY_TITLE, mTitleText.getText().toString()); bundle.putString(NotesDbAdapter.KEY_BODY, mBodyText.getText().toString()); if (mRowId != null) { @@ -562,24 +558,22 @@ protected void onCreate(Bundle savedInstanceState) { }</pre> </li> </ol> - + <h2>Step 11</h2> -<div class="sidebox" style="border:2px solid #FFFFDD;float:right; - background-color:#FFFFEE;margin-right:0px; - margin-bottom:.5em;margin-top:1em;padding:0em;width:240px;"> - <h2 style="border:0;font-size:12px;padding:.5em .5em .5em 1em;margin:0; - background-color:#FFFFDD;">The All-Important Android Manifest File</h2> - <p style="padding-left:.5em;font-size:12px;margin:0; - padding:.0em .5em .5em 1em;">The AndroidManifest.xml file is the way in which Android sees your + <div class="sidebox-wrapper"> + <div class="sidebox"> + <h2>The All-Important Android Manifest File</h2> + <p>The AndroidManifest.xml file is the way in which Android sees your application. This file defines the category of the application, where it shows up (or even if it shows up) in the launcher or settings, what activities, services, and content providers it defines, what intents it can receive, and more. </p> - <p style="padding-left:.5em;font-size:12px;margin:0; - padding:.0em .5em .5em 1em;">For more information, see the reference document - <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">The AndroidManifest.xml File</a></p> - </div> + <p>For more information, see the reference document + <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">The AndroidManifest.xml +File</a></p> + </div> + </div> <p>Finally, the new Activity has to be defined in the manifest file:</p> <p>Before the new Activity can be seen by Android, it needs its own @@ -597,10 +591,10 @@ protected void onCreate(Bundle savedInstanceState) { </li> <li>Click the <strong>Application</strong> tab at the bottom of the Manifest editor.</li> <li>Click <strong>Add...</strong> in the Application Nodes section. - <p>If you see a dialog with radiobuttons at the top, select the top radio button: + <p>If you see a dialog with radiobuttons at the top, select the top radio button: "Create a new element at the top level, in Application".</p></li> <li>Make sure "(A) Activity" is selected in the selection pane of the dialog, and click <strong>OK</strong>.</li> - <li>Click on the new "Activity" node, in the Application Nodes section, then + <li>Click on the new "Activity" node, in the Application Nodes section, then type <code>.NoteEdit</code> into the <em>Name*</em> field to the right. Press Return/Enter.</li> </ol> @@ -608,28 +602,28 @@ protected void onCreate(Bundle savedInstanceState) { file, have a look around at some of the other options available (but be careful not to select them otherwise they will be added to your Manifest). This editor should help you understand and alter the AndroidManifest.xml file as you move on to more advanced Android applications.</p> - + <p class="note">If you prefer to edit this file directly, simply open the <code>AndroidManifest.xml</code> file and look at the source (use the <code>AndroidManifest.xml</code> tab in the eclipse editor to see the source code directly). Then edit the file as follows:<br> - <code><activity android:name=".NoteEdit"></activity></code><br><br> + <code><activity android:name=".NoteEdit" /></code><br><br> This should be placed just below the line that reads:<br> <code></activity></code> for the <code>.Notepadv2</code> activity.</p> <h2 style="clear:right;">Step 12</h2> <p>Now Run it!</p> -<p>You should now be able to add real notes from -the menu, as well as delete an existing one. Notice that in order to delete, you must +<p>You should now be able to add real notes from +the menu, as well as delete an existing one. Notice that in order to delete, you must first use the directional controls on the device to highlight the note. -Furthermore, selecting a note title from the list should bring up the note -editor to let you edit it. Press confirm when finished to save the changes +Furthermore, selecting a note title from the list should bring up the note +editor to let you edit it. Press confirm when finished to save the changes back to the database. <h2>Solution and Next Steps</h2> -<p>You can see the solution to this exercise in <code>Notepadv2Solution</code> +<p>You can see the solution to this exercise in <code>Notepadv2Solution</code> from the zip file to compare with your own.</p> <p>Now try editing a note, and then hitting the back button on the emulator instead of the confirm button (the back button is below the menu button). You |