diff options
Diffstat (limited to 'docs/html/guide/tutorials/notepad/notepad-ex2.jd')
-rw-r--r-- | docs/html/guide/tutorials/notepad/notepad-ex2.jd | 642 |
1 files changed, 0 insertions, 642 deletions
diff --git a/docs/html/guide/tutorials/notepad/notepad-ex2.jd b/docs/html/guide/tutorials/notepad/notepad-ex2.jd deleted file mode 100644 index fed40ab..0000000 --- a/docs/html/guide/tutorials/notepad/notepad-ex2.jd +++ /dev/null @@ -1,642 +0,0 @@ -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. -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> -<ul> -<li><em>Constructing a new Activity and adding it to the Android manifest</em></li> -<li><em>Invoking another Activity asynchronously using <code>startActivityForResult()</code></em></li> -<li><em>Passing data between Activity in Bundle objects</em></li> -<li><em>How to use a more advanced screen layout</em></li> -<li><em>How to create a context menu</em></li> -</ul> - -<div style="float:right;white-space:nowrap"> - [<a href="notepad-ex1.html">Exercise 1</a>] - <span style="color:#BBB;"> - [<a href="notepad-ex2.html" style="color:#DDD;">Exercise 2</a>] - </span> - [<a href="notepad-ex3.html">Exercise 3</a>] - [<a href="notepad-extra-credit.html">Extra Credit</a>] -</div> - -<h2>Step 1</h2> - -<p>Create a new Android project using the sources from <code>Notepadv2</code> under the -<code>NotepadCodeLab</code> folder, just like you did for the first exercise. If you see an error about -<code>AndroidManifest.xml</code>, or some problems related to an -<code>android.zip</code> file, right click on the project and select <strong>Android -Tools</strong> > <strong>Fix Project Properties</strong>.</p> - -<p>Open the <code>Notepadv2</code> project and take a look around:</p> -<ul> - <li> - Open and look at the <code>strings.xml</code> file under - <code>res/values</code> — there are several new strings which we will use - for our new functionality - </li> - <li> - Also, open and take a look at the top of the <code>Notepadv2</code> class, - you will notice several new constants have been defined along with a new <code>mNotesCursor</code> - field used to hold the cursor we are using. - </li> - <li> - Note also that the <code>fillData()</code> method has a few more comments and now uses - the new field to store the notes Cursor. The <code>onCreate()</code> method is - unchanged from the first exercise. Also notice that the member field used to store the - notes Cursor is now called <code>mNotesCursor</code>. The <code>m</code> denotes a member - field and is part of the Android coding style standards. - </li> - <li> - There are also a couple of new overridden methods - (<code>onCreateContextMenu()</code>, <code>onContextItemSelected()</code>, - <code>onListItemClick()</code> and <code>onActivityResult()</code>) - which we will be filling in below. - </li> -</ul> - - -<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 - 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 - the local ListView object for the Activity. Now, each list item in this ListView will activate the - context menu. - <li> - Now fill in the <code>onCreateContextMenu()</code> method. This callback is similar to the other - menu callback used for the options menu. Here, we add just one line, which will add a menu item - to delete a note. Call <code>menu.add()</code> like so: - <pre> -public void onCreateContextMenu(Menu menu, View v, - ContextMenu.ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - menu.add(0, DELETE_ID, 0, R.string.menu_delete); -}</pre> - <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 - step, we'll handle the menu item selection.</p> - </li> -</ol> - -<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 - <code>onContextItemSelected()</code> method like this:</p> -<pre> -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); -}</pre> -<p>Here, we retrieve the {@link android.widget.AdapterView.AdapterContextMenuInfo AdapterContextMenuInfo} -with {@link android.view.MenuItem#getMenuInfo()}. The <var>id</var> field of this object tells us -the position of the item in the ListView. We then pass this to the <code>deleteNote()</code> -method of our NotesDbAdapter and the note is deleted. That's it for the context menu — notes -can now be deleted.</p> - -<h2 style="clear:right;">Step 4</h2> - <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>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> - - <p>Fill in the body of the <code>createNote()</code> method: - <p>Create a new <code>Intent</code> to create a note - (<code>ACTIVITY_CREATE</code>) using the <code>NoteEdit</code> class. - Then fire the Intent using the <code>startActivityForResult()</code> method - call:</p> - <pre style="overflow:auto"> -Intent i = new Intent(this, NoteEdit.class); -startActivityForResult(i, ACTIVITY_CREATE);</pre> - <p>This form of the Intent call targets a specific class in our Activity, in this case - <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 - 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 - of calling it — in this manner, our Activity is not informed when the Activity is completed, and there is - no way to return result information from the called Activity with <code>startActivity()</code>. - <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> - - <p>Fill in the body of the <code>onListItemClick()</code> override.</p> - <p><code>onListItemClick()</code> is a callback method that we'll override. It is called when - the user selects an item from the list. It is passed four parameters: the - <code>ListView</code> object it was invoked from, the <code>View</code> - inside the <code>ListView</code> that was clicked on, the - <code>position</code> in the list that was clicked, and the - <code>mRowId</code> of the item that was clicked. In this instance we can - ignore the first two parameters (we only have one <code>ListView</code> it - could be), and we ignore the <code>mRowId</code> as well. All we are - 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 - <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 - to pass in the title and body text, and the <code>mRowId</code> for the note we are - editing. Finally, it will fire the Intent using the - <code>startActivityForResult()</code> method call. Here's the code that - belongs in <code>onListItemClick()</code>:</p> - <pre> -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);</pre> - <ul> - <li> - <code>putExtra()</code> is the method to add items into the extras Bundle - to pass in to intent invocations. Here, we are - using the Bundle to pass in the title, body and mRowId of the note we want to edit. - </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 - 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> - the Intent and the request code. (The request code will be - returned to <code>onActivityResult</code> as the <code>requestCode</code> parameter.)</li> - </ul> - <p class="note"><b>Note:</b> We assign the mNotesCursor field to a local variable at the - start of the method. This is done as an optimization of the Android code. Accessing a local - 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> - -<p>The above <code>createNote()</code> and <code>onListItemClick()</code> - methods use an asynchronous Intent invocation. We need a handler for the callback, so here we fill - in the body of the <code>onActivityResult()</code>. </p> -<p><code>onActivityResult()</code> is the overridden method - which will be called when an Activity returns with a result. (Remember, an Activity - will only return a result if launched with <code>startActivityForResult</code>.) The parameters provided - to the callback are: </p> - <ul> - <li><code>requestCode</code> — the original request code - specified in the Intent invocation (either <code>ACTIVITY_CREATE</code> or - <code>ACTIVITY_EDIT</code> for us). - </li> - <li><code>resultCode</code> — the result (or error code) of the call, this - should be zero if everything was OK, but may have a non-zero code indicating - that something failed. There are standard result codes available, and you - can also create your own constants to indicate specific problems. - </li> - <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> - <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 - another and share services.</p> - <p>Here's the code that belongs in your <code>onActivityResult()</code>:</p> - <pre> -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; -}</pre> - - <ul> - <li> - We are handling both the <code>ACTIVITY_CREATE</code> and - <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 - returned Intent) and use them to create a new note. - </li> - <li> - In the case of an edit, we pull the mRowId as well, and use that to update - the note in the database. - </li> - <li> - <code>fillData()</code> at the end ensures everything is up to date . - </li> - </ul> - - -<h2>Step 7</h2> - - <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>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">XML Layouts</a> is an essential part of -creating - a good looking Android application.</p> - <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> - <p>This is the most - sophisticated UI we have dealt with yet. The file is given to you to avoid - problems that may sneak in when typing the code. (The XML is very strict - about case sensitivity and structure, mistakes in these are the usual cause - of problems with layout.)</p> - <p>There is a new parameter used - here that we haven't seen before: <code>android:layout_weight</code> (in - this case set to use the value 1 in each case).</p> - <p><code>layout_weight</code> is used in LinearLayouts - to assign "importance" to Views within the layout. All Views have a default - <code>layout_weight</code> of zero, meaning they take up only as much room - on the screen as they need to be displayed. Assigning a value higher than - zero will split up the rest of the available space in the parent View, according - to the value of each View's <code>layout_weight</code> and its ratio to the - overall <code>layout_weight</code> specified in the current layout for this - and other View elements.</p> - <p>To give an example: let's say we have a text label - and two text edit elements in a horizontal row. The label has no - <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). - 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 - second (because we claim the second one is more important).</p> - <p>This layout also demonstrates how to nest multiple layouts - inside each other to achieve a more complex and pleasant layout. In this - example, a horizontal linear layout is nested inside the vertical one to - allow the title label and text field to be alongside each other, - horizontally.</p> - - -<h2 style="clear:right;">Step 8</h2> - - <p>Create a <code>NoteEdit</code> class that extends - <code>android.app.Activity</code>.</p> - <p>This is the first time we will have - created an Activity without the Android Eclipse plugin doing it for us. When - you do so, the <code>onCreate()</code> method is not automatically - overridden for you. It is hard to imagine an Activity that doesn't override - the <code>onCreate()</code> method, so this should be the first thing you do.</p> - <ol> - <li>Right click on the <code>com.android.demo.notepad2</code> package - in the Package Explorer, and select <strong>New</strong> > <strong>Class</strong> from the popup - menu.</li> - <li>Fill in <code>NoteEdit</code> for the <code>Name:</code> field in the - dialog.</li> - <li>In the <code>Superclass:</code> field, enter - <code>android.app.Activity</code> (you can also just type Activity and hit - Ctrl-Space on Windows and Linux or Cmd-Space on the Mac, to invoke code - assist and find the right package and class).</li> - <li>Click <strong>Finish</strong>.</li> - <li>In the resulting <code>NoteEdit</code> class, right click in the editor - window and select <strong>Source</strong> > <strong>Override/Implement Methods...</strong></li> - <li>Scroll down through the checklist in the dialog until you see - <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> - -<p>This will set the title of our new Activity to say "Edit Note" (one - of the strings defined in <code>strings.xml</code>). It will also set the - content view to use our <code>note_edit.xml</code> layout file. We can then - grab handles to the title and body text edit views, and the confirm button, - so that our class can use them to set and get the note title and body, - and attach an event to the confirm button for when it is pressed by the - user.</p> - <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 - track of what note the user is editing.</p> - - <ol> - <li> - Inside <code>onCreate()</code>, set up the layout:<br> - <pre>setContentView(R.layout.note_edit);</pre> - </li> - <li> - Find the edit and button components we need: - <p>These are found by the - IDs associated to them in the R class, and need to be cast to the right - type of <code>View</code> (<code>EditText</code> for the two text views, - and <code>Button</code> for the confirm button):</p> - <pre> -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 - 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 - <code>mRowId</code> from the extras Bundle in - the Intent (if it is present):<br> - <pre> -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); - } - if (body != null) { - mBodyText.setText(body); - } -}</pre> - <ul> - <li> - We are pulling the <code>title</code> and - <code>body</code> out of the - <code>extras</code> Bundle that was set from the - Intent invocation. - </li><li> - We also null-protect the text field setting (i.e., we don't want to set - the text fields to null accidentally).</li> - </ul> - </li> - <li> - Create an <code>onClickListener()</code> for the button: - <p>Listeners can be one of the more confusing aspects of UI - implementation, but - what we are trying to achieve in this case is simple. We want an - <code>onClick()</code> method to be called when the user presses the - confirm button, and use that to do some work and return the values - of the edited note to the Intent caller. We do this using something called - an anonymous inner class. This is a bit confusing to look at unless you - have seen them before, but all you really need to take away from this is - that you can refer to this code in the future to see how to create a - listener and attach it to a button. (Listeners are a common idiom - in Java development, particularly for user interfaces.) Here's the empty listener:<br> - <pre> -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 - back to the Activity that invoked this <code>NoteEdit</code> Activity. If the - operation is an edit rather than a create, we also want to put the - <code>mRowId</code> into the Bundle so that the - <code>Notepadv2</code> class can save the changes back to the correct - note.</p> - <ol> - <li> - Create a <code>Bundle</code> and put the title and body text into it using the - 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) { - bundle.putLong(NotesDbAdapter.KEY_ROWID, mRowId); -}</pre> - </li> - <li> - Set the result information (the Bundle) in a new Intent and finish the Activity: - <pre> -Intent mIntent = new Intent(); -mIntent.putExtras(bundle); -setResult(RESULT_OK, mIntent); -finish();</pre> - <ul> - <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 - Intent caller. In this case everything worked, so we return RESULT_OK for the - result code.</li> - <li>The <code>finish()</code> call is used to signal that the Activity - is done (like a return call). Anything set in the Result will then be - returned to the caller, along with execution control.</li> - </ul> - </li> - </ol> - <p>The full <code>onCreate()</code> method (plus supporting class fields) should - now look like this:</p> - <pre> -private EditText mTitleText; -private EditText mBodyText; -private Long mRowId; - -@Override -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); - } - if (body != null) { - 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) { - bundle.putLong(NotesDbAdapter.KEY_ROWID, mRowId); - } - - Intent mIntent = new Intent(); - mIntent.putExtras(bundle); - setResult(RESULT_OK, mIntent); - finish(); - } - }); -}</pre> - </li> - </ol> - -<h2>Step 11</h2> - - <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>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 - Activity entry in the <code>AndroidManifest.xml</code> file. This is to let - the system know that it is there and can be called. We could also specify - which IntentFilters the activity implements here, but we are going to skip - this for now and just let Android know that the Activity is - defined.</p> - <p>There is a Manifest editor included in the Eclipse plugin that makes it much easier - to edit the AndroidManifest file, and we will use this. If you prefer to edit the file directly - or are not using the Eclipse plugin, see the box at the end for information on how to do this - without using the new Manifest editor.<p> - <ol> - <li>Double click on the <code>AndroidManifest.xml</code> file in the package explorer to open it. - </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: - "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 - type <code>.NoteEdit</code> into the <em>Name*</em> - field to the right. Press Return/Enter.</li> - </ol> - <p>The Android Manifest editor helps you add more complex entries into the AndroidManifest.xml - 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" /></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 -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 -back to the database. - -<h2>Solution and Next Steps</h2> - -<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 -will see an error come up. Clearly our application still has some problems. -Worse still, if you did make some changes and hit the back button, when you go -back into the notepad to look at the note you changed, you will find that all -your changes have been lost. In the next exercise we will fix these -problems.</p> - -<p> -Once you are ready, move on to <a href="notepad-ex3.html">Tutorial -Exercise 3</a> where you will fix the problems with the back button and lost -edits by introducing a proper life cycle into the NoteEdit Activity.</p> - - |