Merge "Update Notepad tutorial documentation to match code"
This commit is contained in:
Binary file not shown.
@@ -5,7 +5,7 @@ parent.link=index.html
|
||||
|
||||
|
||||
<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>
|
||||
@@ -75,7 +75,7 @@ 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 +91,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 +102,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) {
|
||||
@@ -127,15 +127,15 @@ can now be deleted.</p>
|
||||
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;
|
||||
<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}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
|
||||
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 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
|
||||
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
|
||||
@@ -155,7 +155,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 +164,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 +180,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 +207,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 +219,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 +243,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 +277,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,7 +288,7 @@ case ACTIVITY_EDIT:
|
||||
<code>fillData()</code> at the end ensures everything is up to date .
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<h2>Step 7</h2>
|
||||
|
||||
@@ -305,8 +305,8 @@ case ACTIVITY_EDIT:
|
||||
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
|
||||
<p style="padding-left:.5em;font-size:12px;margin:0;
|
||||
padding:.0em .5em .5em 1em;">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>
|
||||
@@ -335,7 +335,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 +373,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 +388,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 +406,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 +423,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 +459,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 +483,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 +498,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 +521,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 +541,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,7 +562,7 @@ protected void onCreate(Bundle savedInstanceState) {
|
||||
}</pre>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
|
||||
<h2>Step 11</h2>
|
||||
|
||||
<div class="sidebox" style="border:2px solid #FFFFDD;float:right;
|
||||
@@ -570,16 +570,16 @@ protected void onCreate(Bundle savedInstanceState) {
|
||||
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
|
||||
<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
|
||||
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
|
||||
<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>
|
||||
</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 +597,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 +608,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
|
||||
|
||||
@@ -36,7 +36,7 @@ notes.</p>
|
||||
|
||||
<ol>
|
||||
<li>Remove the code in <code>NoteEdit</code> that parses the title and body
|
||||
from the extras Bundle.
|
||||
from the extras Bundle.
|
||||
<p>Instead, we are going to use the <code>DBHelper</code> class
|
||||
to access the notes from the database directly. All we need passed into the
|
||||
NoteEdit Activity is a <code>mRowId</code> (but only if we are editing, if creating we pass
|
||||
@@ -57,7 +57,7 @@ if (body != null) {
|
||||
}</pre>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
|
||||
<h2>Step 2</h2>
|
||||
|
||||
<p>Create a class field for a <code>NotesDbAdapter</code> at the top of the NoteEdit class:</p>
|
||||
@@ -67,11 +67,11 @@ if (body != null) {
|
||||
<pre>
|
||||
mDbHelper = new NotesDbAdapter(this);<br>
|
||||
mDbHelper.open();</pre>
|
||||
|
||||
|
||||
<h2>Step 3</h2>
|
||||
|
||||
<p>In <code>NoteEdit</code>, we need to check the <var>savedInstanceState</var> for the
|
||||
<code>mRowId</code>, in case the note
|
||||
<code>mRowId</code>, in case the note
|
||||
editing contains a saved state in the Bundle, which we should recover (this would happen
|
||||
if our Activity lost focus and then restarted).</p>
|
||||
<ol>
|
||||
@@ -87,11 +87,11 @@ if (body != null) {
|
||||
</pre>
|
||||
with this:
|
||||
<pre>
|
||||
mRowId = savedInstanceState != null ? savedInstanceState.getLong(NotesDbAdapter.KEY_ROWID)
|
||||
: null;
|
||||
mRowId = (savedInstanceState == null) ? null :
|
||||
(Long) savedInstanceState.getSerializable(NotesDbAdapter.KEY_ROWID);
|
||||
if (mRowId == null) {
|
||||
Bundle extras = getIntent().getExtras();
|
||||
mRowId = extras != null ? extras.getLong(NotesDbAdapter.KEY_ROWID)
|
||||
Bundle extras = getIntent().getExtras();
|
||||
mRowId = extras != null ? extras.getLong(NotesDbAdapter.KEY_ROWID)
|
||||
: null;
|
||||
}
|
||||
</pre>
|
||||
@@ -100,10 +100,15 @@ if (body != null) {
|
||||
Note the null check for <code>savedInstanceState</code>, and we still need to load up
|
||||
<code>mRowId</code> from the <code>extras</code> Bundle if it is not
|
||||
provided by the <code>savedInstanceState</code>. This is a ternary operator shorthand
|
||||
to safely either use the value or null if it is not present.
|
||||
to safely either use the value or null if it is not present.
|
||||
</li>
|
||||
<li>
|
||||
Note the use of <code>Bundle.getSerializable()</code> instead of
|
||||
<code>Bundle.getLong()</code>. The latter encoding returns a <code>long</code> primitive and
|
||||
so can not be used to represent the case when <code>mRowId</code> is <code>null</code>.
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
|
||||
<h2>Step 4</h2>
|
||||
|
||||
<p>Next, we need to populate the fields based on the <code>mRowId</code> if we
|
||||
@@ -126,38 +131,38 @@ public void onClick(View view) {
|
||||
}</pre>
|
||||
<p>We will take care of storing the updates or new notes in the database
|
||||
ourselves, using the life-cycle methods.</p>
|
||||
|
||||
|
||||
<p>The whole <code>onCreate()</code> method should now look like this:</p>
|
||||
<pre>
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
|
||||
mDbHelper = new NotesDbAdapter(this);
|
||||
mDbHelper.open();
|
||||
|
||||
|
||||
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 = savedInstanceState != null ? savedInstanceState.getLong(NotesDbAdapter.KEY_ROWID)
|
||||
: null;
|
||||
|
||||
mRowId = (savedInstanceState == null) ? null :
|
||||
(Long) savedInstanceState.getSerializable(NotesDbAdapter.KEY_ROWID);
|
||||
if (mRowId == null) {
|
||||
Bundle extras = getIntent().getExtras();
|
||||
mRowId = extras != null ? extras.getLong(NotesDbAdapter.KEY_ROWID)
|
||||
mRowId = extras != null ? extras.getLong(NotesDbAdapter.KEY_ROWID)
|
||||
: null;
|
||||
}
|
||||
|
||||
|
||||
populateFields();
|
||||
|
||||
|
||||
confirmButton.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
public void onClick(View view) {
|
||||
setResult(RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
|
||||
|
||||
});</pre>
|
||||
|
||||
<h2>Step 6</h2>
|
||||
@@ -180,7 +185,7 @@ is an Android convenience method provided to take care of the Cursor life-cycle.
|
||||
and re-create resources as dictated by the Activity life-cycle, so we don't need to worry about
|
||||
doing that ourselves. After that, we just look up the title and body values from the Cursor
|
||||
and populate the View elements with them.</p>
|
||||
|
||||
|
||||
|
||||
<h2>Step 7</h2>
|
||||
|
||||
@@ -189,12 +194,12 @@ and populate the View elements with them.</p>
|
||||
margin-top:1em;padding:0em;width:240px;">
|
||||
<h2 style="border:0;font-size:12px;padding:.5em .5em .5em 1em;margin:0;
|
||||
background-color:#FFFFDD;">Why handling life-cycle events is important</h2>
|
||||
<p style="padding-left:.5em;font-size:12px;margin:0;
|
||||
<p style="padding-left:.5em;font-size:12px;margin:0;
|
||||
padding:.0em .5em .5em 1em;">If you are used to always having control in your applications, you
|
||||
might not understand why all this life-cycle work is necessary. The reason
|
||||
is that in Android, you are not in control of your Activity, the
|
||||
is that in Android, you are not in control of your Activity, the
|
||||
operating system is!</p>
|
||||
<p style="padding-left:.5em;font-size:12px;margin:0;
|
||||
<p style="padding-left:.5em;font-size:12px;margin:0;
|
||||
padding:.0em .5em .5em 1em;">As we have already seen, the Android model is based around activities
|
||||
calling each other. When one Activity calls another, the current Activity
|
||||
is paused at the very least, and may be killed altogether if the
|
||||
@@ -209,9 +214,9 @@ and populate the View elements with them.</p>
|
||||
out while the call Activity takes over.</p>
|
||||
</div>
|
||||
|
||||
<p>Still in the <code>NoteEdit</code> class, we now override the methods
|
||||
<code>onSaveInstanceState()</code>, <code>onPause()</code> and
|
||||
<code>onResume()</code>. These are our life-cycle methods
|
||||
<p>Still in the <code>NoteEdit</code> class, we now override the methods
|
||||
<code>onSaveInstanceState()</code>, <code>onPause()</code> and
|
||||
<code>onResume()</code>. These are our life-cycle methods
|
||||
(along with <code>onCreate()</code> which we already have).</p>
|
||||
|
||||
<p><code>onSaveInstanceState()</code> is called by Android if the
|
||||
@@ -241,8 +246,10 @@ and populate the View elements with them.</p>
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putLong(NotesDbAdapter.KEY_ROWID, mRowId);
|
||||
saveState();
|
||||
outState.putSerializable(NotesDbAdapter.KEY_ROWID, mRowId);
|
||||
}</pre>
|
||||
<p>We'll define <code>saveState()</code> next.</p>
|
||||
</li>
|
||||
<li><code>
|
||||
onPause()</code>:
|
||||
@@ -252,7 +259,6 @@ and populate the View elements with them.</p>
|
||||
super.onPause();
|
||||
saveState();
|
||||
}</pre>
|
||||
<p>We'll define <code>saveState()</code> next.</p>
|
||||
</li>
|
||||
<li><code>
|
||||
onResume()</code>:
|
||||
@@ -264,6 +270,10 @@ and populate the View elements with them.</p>
|
||||
}</pre>
|
||||
</li>
|
||||
</ol>
|
||||
<p>Note that <code>saveState()</code> must be called in both <code>onSaveInstanceState()</code>
|
||||
and <code>onPause()</code> to ensure that the data is saved. This is because there is no
|
||||
guarantee that <code>onSaveInstanceState()</code> will be called and because when it <em>is</em>
|
||||
called, it is called before <code>onPause()</code>.</p>
|
||||
|
||||
|
||||
<h2 style="clear:right;">Step 8</h2>
|
||||
@@ -301,19 +311,18 @@ database.</p>
|
||||
necessary. The resulting method should look like this:</p>
|
||||
<pre>
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode,
|
||||
Intent intent) {
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
||||
super.onActivityResult(requestCode, resultCode, intent);
|
||||
fillData();
|
||||
}</pre>
|
||||
|
||||
<p>Because the other class now does the work, all this has to do is refresh
|
||||
the data.</p>
|
||||
|
||||
|
||||
<h2>Step 10</h2>
|
||||
|
||||
<p>Also remove the lines which set the title and body from the
|
||||
<code>onListItemClick()</code> method (again they are no longer needed,
|
||||
<code>onListItemClick()</code> method (again they are no longer needed,
|
||||
only the <code>mRowId</code> is):</p>
|
||||
<pre>
|
||||
Cursor c = mNotesCursor;
|
||||
@@ -344,13 +353,13 @@ so that all that should be left in that method is:
|
||||
other occurrences of <code>mNotesCursor</code> in your <code>fillData()</code> method.
|
||||
</ol>
|
||||
<p>
|
||||
Run it! (use <em>Run As -> Android Application</em> on the project right
|
||||
Run it! (use <em>Run As -> Android Application</em> on the project right
|
||||
click menu again)</p>
|
||||
|
||||
<h2>Solution and Next Steps</h2>
|
||||
|
||||
<p>You can see the solution to this exercise in <code>Notepadv3Solution</code>
|
||||
from
|
||||
from
|
||||
the zip file to compare with your own.</p>
|
||||
<p>
|
||||
When you are ready, move on to the <a href="notepad-extra-credit.html">Tutorial
|
||||
|
||||
Reference in New Issue
Block a user