1page.title=Notepad Exercise 1 2parent.title=Notepad Tutorial 3parent.link=index.html 4@jd:body 5 6 7<p><em>In this exercise, you will construct a simple notes list that lets the 8user add new notes but not edit them. The exercise demonstrates:</em></p> 9<ul> 10<li><em>The basics of <code>ListActivities</code> and creating and handling menu 11options. </em></li> 12<li><em>How to use a SQLite database to store the notes.</em></li> 13<li><em>How to bind data from a database cursor into a ListView using a 14SimpleCursorAdapter.</em></li> 15<li><em>The basics of screen layouts, including how to lay out a list view, how 16you can add items to the activity menu, and how the activity handles those menu 17selections. </em></li> 18</ul> 19 20<div style="float:right;white-space:nowrap"> 21<span style="color:#BBB;"> 22 [<a href="notepad-ex1.html" style="color:#BBB;">Exercise 1</a>]</span> 23 [<a href="notepad-ex2.html">Exercise 2</a>] 24 [<a href="notepad-ex3.html">Exercise 3</a>] 25 [<a href="notepad-extra-credit.html">Extra Credit</a>] 26</div> 27 28 29 30<h2>Step 1</h2> 31 32 <p>Open up the <code>Notepadv1</code> project in Eclipse.</p> 33 34 <p><code>Notepadv1</code> is a project that is provided as a starting point. It 35 takes care of some of the boilerplate work that you have already seen if you 36 followed the <a href="{@docRoot}guide/tutorials/hello-world.html">Hello, 37 World</a> tutorial.</p> 38 39 <ol> 40 <li> 41 Start a new Android Project by clicking <strong>File</strong> > 42 <strong>New</strong> > <strong>Android Project</strong>.</li> 43 <li> 44 In the New Android Project dialog, select <strong>Create project from existing source</strong>.</li> 45 <li> 46 Click <strong>Browse</strong> and navigate to where you copied the <code>NotepadCodeLab</code> 47 (downloaded during <a href="{@docRoot}guide/tutorials/notepad/index.html#preparing">setup</a>) 48 and select <code>Notepadv1</code>.</li> 49 <li> 50 The Project Name and other properties should be automatically filled for you. 51 You must select the Build Target—we recommend selecting a target with the 52 lowest platform version available. Also add an integer to the Min SDK Version field 53 that matches the API Level of the selected Build Target.</li> 54 <li> 55 Click <strong>Finish</strong>. The <code>Notepadv1</code> project should open and be 56 visible in your Eclipse package explorer.</li> 57 </ol> 58 59 <p>If you see an error about <code>AndroidManifest.xml</code>, or some 60 problems related to an Android zip file, right click on the project and 61 select <strong>Android Tools</strong> > <strong>Fix Project Properties</strong>. 62 (The project is looking in the wrong location for the library file, 63 this will fix it for you.)</p> 64 65 <h2>Step 2</h2> 66 67 <div class="sidebox" style="border:2px solid #FFFFDD;float:right; 68 background-color:#FFFFEE;margin-right:0px; 69 margin-bottom:.5em;margin-top:1em;padding:0em;width:240px;"> 70 <h2 style="border:0;font-size:12px;padding:.5em .5em .5em 1em;margin:0; 71 background-color:#FFFFDD;">Accessing and modifying data</h2> 72 <p style="padding-left:.5em;font-size:12px;margin:0; padding:.0em .5em .5em 1em;">For this 73 exercise, we are using a SQLite database to store our data. This is useful 74 if only <em>your</em> application will need to access or modify the data. If you wish for 75 other activities to access or modify the data, you have to expose the data using a 76 {@link android.content.ContentProvider ContentProvider}.</p> 77 <p style="padding-left:.5em;font-size:12px;margin:0; 78 padding:.0em .5em .5em 1em;">If you are interested, you can find out more about 79 <a href="{@docRoot}guide/topics/providers/content-providers.html">content providers</a> or the whole 80 subject of <a href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a>. 81 The NotePad sample in the <code>samples/</code> folder of the SDK also has an example of how 82 to create a ContentProvider.</p> 83 </div> 84 85 <p>Take a look at the <code>NotesDbAdapter</code> class — this class is provided to 86 encapsulate data access to a SQLite database that will hold our notes data 87 and allow us to update it.</p> 88 <p>At the top of the class are some constant definitions that will be used in the application 89 to look up data from the proper field names in the database. There is also a database creation 90 string defined, which is used to create a new database schema if one doesn't exist already.</p> 91 <p>Our database will have the name <code>data</code>, and have a single table called 92 <code>notes</code>, which in turn has three fields: <code>_id</code>, <code>title</code> and 93 <code>body</code>. The <code>_id</code> is named with an underscore convention used in a number of 94 places inside the Android SDK and helps keep a track of state. The <code>_id</code> 95 usually has to be specified when querying or updating the database (in the column projections 96 and so on). The other two fields are simple text fields that will store data. 97 </p> 98 <p>The constructor for <code>NotesDbAdapter</code> takes a Context, which allows it to communicate with aspects 99 of the Android operating system. This is quite common for classes that need to touch the 100 Android system in some way. The Activity class implements the Context class, so usually you will just pass 101 <code>this</code> from your Activity, when needing a Context.</p> 102 <p>The <code>open()</code> method calls up an instance of DatabaseHelper, which is our local 103 implementation of the SQLiteOpenHelper class. It calls <code>getWritableDatabase()</code>, 104 which handles creating/opening a database for us.</p> 105 <p><code>close()</code> just closes the database, releasing resources related to the 106 connection.</p> 107 <p><code>createNote()</code> takes strings for the title and body of a new note, 108 then creates that note in the database. Assuming the new note is created successfully, the 109 method also returns the row <code>_id</code> value for the newly created note.</p> 110 <p><code>deleteNote()</code> takes a <var>rowId</var> for a particular note, and deletes that note from 111 the database.</p> 112 113 <p><code>fetchAllNotes()</code> issues a query to return a {@link android.database.Cursor} over all notes in the 114 database. The <code>query()</code> call is worth examination and understanding. The first field is the 115 name of the database table to query (in this case <code>DATABASE_TABLE</code> is "notes"). 116 The next is the list of columns we want returned, in this case we want the <code>_id</code>, 117 <code>title</code> and <code>body</code> columns so these are specified in the String array. 118 The remaining fields are, in order: <code>selection</code>, 119 <code>selectionArgs</code>, <code>groupBy</code>, <code>having</code> and <code>orderBy</code>. 120 Having these all <code>null</code> means we want all data, need no grouping, and will take the default 121 order. See {@link android.database.sqlite.SQLiteDatabase SQLiteDatabase} for more details.</p> 122 <p class="note"><b>Note:</b> A Cursor is returned rather than a collection of rows. This allows 123 Android to use resources efficiently -- instead of putting lots of data straight into memory 124 the cursor will retrieve and release data as it is needed, which is much more efficient for 125 tables with lots of rows.</p> 126 127 <p><code>fetchNote()</code> is similar to <code>fetchAllNotes()</code> but just gets one note 128 with the <var>rowId</var> we specify. It uses a slightly different version of the 129 {@link android.database.sqlite.SQLiteDatabase} <code>query()</code> method. 130 The first parameter (set <em>true</em>) indicates that we are interested 131 in one distinct result. The <var>selection</var> parameter (the fourth parameter) has been specified to search 132 only for the row "where _id =" the <var>rowId</var> we passed in. So we are returned a Cursor on 133 the one row.</p> 134 <p>And finally, <code>updateNote()</code> takes a <var>rowId</var>, <var>title</var> and <var>body</var>, and uses a 135 {@link android.content.ContentValues ContentValues} instance to update the note of the given 136 <var>rowId</var>.</p> 137 138<h2 style="clear:right;">Step 3</h2> 139 140 <div class="sidebox" style="border:2px solid #FFFFDD;float:right; 141 background-color:#FFFFEE;margin-right:0px; 142 margin-bottom:.5em;margin-top:1em;padding:0em;width:240px;"> 143 <h2 style="border:0;font-size:12px;padding:.5em .5em .5em 1em;margin:0; 144 background-color:#FFFFDD;">Layouts and activities</h2> 145 <p style="padding-left:.5em;font-size:12px;margin:0; 146 padding:.0em .5em .5em 1em;">Most Activity classes will have a layout associated with them. The layout 147 will be the "face" of the Activity to the user. In this case our layout will 148 take over the whole screen and provide a list of notes.</p> 149 <p style="padding-left:.5em;font-size:12px;margin:0; 150 padding:.0em .5em .5em 1em;">Full screen layouts are not the only option for an Activity however. You 151 might also want to use a <a 152href="{@docRoot}guide/appendix/faq/commontasks.html#floatingorfull">floating 153 layout</a> (for example, a <a 154href="{@docRoot}guide/appendix/faq/commontasks.html#dialogsandalerts">dialog 155 or alert</a>), 156 or perhaps you don't need a layout at all (the Activity will be invisible 157 to the user unless you specify some kind of layout for it to use).</p> 158 </div> 159 160 <p>Open the <code>notepad_list.xml</code> file in <code>res/layout</code> 161and 162 take a look at it. (You may have to 163 hit the <em>xml</em> tab, at the bottom, in order to view the XML markup.)</p> 164 165 <p>This is a mostly-empty layout definition file. Here are some 166 things you should know about a layout file:</p> 167 168 169 <ul> 170 <li> 171 All Android layout files must start with the XML header line: 172 <code><?xml version="1.0" encoding="utf-8"?></code>. </li> 173 <li> 174 The next definition will often (but not always) be a layout 175 definition of some kind, in this case a <code>LinearLayout</code>. </li> 176 <li> 177 The XML namespace of Android should always be defined in 178 the top level component or layout in the XML so that <code>android:</code> tags can 179 be used through the rest of the file: 180 <p><code>xmlns:android="http://schemas.android.com/apk/res/android"</code></p> 181 </li> 182 </ul> 183 184 <h2 style="clear:right;">Step 4</h2> 185 <p>We need to create the layout to hold our list. Add code inside 186 of the <code>LinearLayout</code> element so the whole file looks like this: </p> 187 <pre> 188<?xml version="1.0" encoding="utf-8"?> 189<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 190 android:layout_width="wrap_content" 191 android:layout_height="wrap_content"> 192 193 <ListView android:id="@android:id/list" 194 android:layout_width="wrap_content" 195 android:layout_height="wrap_content"/> 196 <TextView android:id="@android:id/empty" 197 android:layout_width="wrap_content" 198 android:layout_height="wrap_content" 199 android:text="@string/no_notes"/> 200 201</LinearLayout> 202</pre> 203 <ul> 204 <li> 205 The <strong>@</strong> symbol in the id strings of the <code>ListView</code> and 206 <code>TextView</code> tags means 207 that the XML parser should parse and expand the rest of 208 the id string and use an ID resource.</li> 209 <li> 210 The <code>ListView</code> and <code>TextView</code> can be 211 thought as two alternative views, only one of which will be displayed at once. 212 ListView will be used when there are notes to be shown, while the TextView 213 (which has a default value of "No Notes Yet!" defined as a string 214 resource in <code>res/values/strings.xml</code>) will be displayed if there 215 aren't any notes to display.</li> 216 <li>The <code>list</code> and <code>empty</code> IDs are 217 provided for us by the Android platform, so, we must 218 prefix the <code>id</code> with <code>android:</code> (e.g., <code>@android:id/list</code>).</li> 219 <li>The View with the <code>empty</code> id is used 220 automatically when the {@link android.widget.ListAdapter} has no data for the ListView. The 221 ListAdapter knows to look for this name by default. Alternatively, you could change the 222 default empty view by using {@link android.widget.AdapterView#setEmptyView(View)} 223 on the ListView. 224 <p> 225 More broadly, the <code>android.R</code> class is a set of predefined 226 resources provided for you by the platform, while your project's 227 <code>R</code> class is the set of resources your project has defined. 228 Resources found in the <code>android.R</code> resource class can be 229 used in the XML files by using the <code>android:</code> name space prefix 230 (as we see here).</p> 231 </li> 232 </ul> 233 234 <h2 style="clear:right;">Step 5</h2> 235 236 <div class="sidebox" style="border:2px solid #FFFFDD;float:right; 237 background-color:#FFFFEE;margin-right:0px; 238 margin-bottom:.5em;margin-top:1em;padding:0em;width:240px;"> 239 <h2 style="border:0;font-size:12px;padding:.5em .5em .5em 1em;margin:0; 240 background-color:#FFFFDD;">Resources and the R class</h2> 241 <p style="padding-left:.5em;font-size:12px;margin:0; 242 padding:.0em .5em .5em 1em;">The folders under res/ in the Eclipse project are for resources. 243 There is a <a href="{@docRoot}guide/appendix/faq/commontasks.html#filelist">specific structure</a> to the 244 folders and files under res/.</p> 245 <p style="padding-left:.5em;font-size:12px; 246margin:0; padding:.0em .5em .5em 1em;">Resources defined in these folders and files will have 247 corresponding entries in the R class allowing them to be easily accessed 248 and used from your application. The R class is automatically generated using the contents 249 of the res/ folder by the eclipse plugin (or by aapt if you use the command line tools). 250 Furthermore, they will be bundled and deployed for you as part of the application.</p> 251 </p> 252 </div> 253 <p>To make the list of notes in the ListView, we also need to define a View for each row:</p> 254 <ol> 255 <li> 256 Create a new file under <code>res/layout</code> called 257 <code>notes_row.xml</code>. </li> 258 <li> 259 Add the following contents (note: again the XML header is used, and the 260 first node defines the Android XML namespace)<br> 261 <pre style="overflow:auto"> 262<?xml version="1.0" encoding="utf-8"?> 263<TextView android:id="@+id/text1" 264 xmlns:android="http://schemas.android.com/apk/res/android" 265 android:layout_width="wrap_content" 266 android:layout_height="wrap_content"/></pre> 267 <p> 268 This is the View that will be used for each notes title row — it has only 269 one text field in it. </p> 270 <p>In this case we create a new id called <code>text1</code>. The 271 <strong>+</strong> after the <strong>@</strong> in the id string indicates that the id should 272 be automatically created as a resource if it does not already exist, so we are defining 273 <code>text1</code> on the fly and then using it.</p> 274 </li> 275 <li>Save the file.</li> 276 </ol> 277 <p>Open the <code>R.java</code> class in the 278 project and look at it, you should see new definitions for 279 <code>notes_row</code> and <code>text1</code> (our new definitions) 280 meaning we can now gain access to these from the our code. </p> 281 282 <h2 style="clear:right;">Step 6</h2> 283<p>Next, open the <code>Notepadv1</code> class in the source. In the following steps, we are going to 284 alter this class to become a list adapter and display our notes, and also 285 allow us to add new notes.</p> 286 287<p><code>Notepadv1</code> will inherit from a subclass 288 of <code>Activity</code> called a <code>ListActivity</code>, 289 which has extra functionality to accommodate the kinds of 290 things you might want to do with a list, for 291 example: displaying an arbitrary number of list items in rows on the screen, 292 moving through the list items, and allowing them to be selected.</p> 293 294<p>Take a look through the existing code in <code>Notepadv1</code> class. 295 There is a currently an unused private field called <code>mNoteNumber</code> that 296 we will use to create numbered note titles.</p> 297 <p>There are also three override methods defined: 298 <code>onCreate</code>, <code>onCreateOptionsMenu</code> and 299 <code>onOptionsItemSelected</code>; we need to fill these 300 out:</p> 301 <ul> 302 <li><code>onCreate()</code> is called when the activity is 303 started — it is a little like the "main" method for an Activity. We use 304 this to set up resources and state for the activity when it is 305 running.</li> 306 <li><code>onCreateOptionsMenu()</code> is used to populate the 307 menu for the Activity. This is shown when the user hits the menu button, 308and 309 has a list of options they can select (like "Create 310 Note"). </li> 311 <li><code>onOptionsItemSelected()</code> is the other half of the 312 menu equation, it is used to handle events generated from the menu (e.g., 313 when the user selects the "Create Note" item). 314 </li> 315 </ul> 316 317 <h2>Step 7</h2> 318 <p>Change the inheritance of <code>Notepadv1</code> from 319<code>Activity</code> 320 to <code>ListActivity</code>:</p> 321 <pre>public class Notepadv1 extends ListActivity</pre> 322 <p>Note: you will have to import <code>ListActivity</code> into the 323Notepadv1 324 class using Eclipse, <strong>ctrl-shift-O</strong> on Windows or Linux, or 325 <strong>cmd-shift-O</strong> on the Mac (organize imports) will do this for you 326 after you've written the above change.</p> 327 328 <h2>Step 8</h2> 329 <p>Fill out the body of the <code>onCreate()</code> method.</p> 330 <p>Here we will set the title for the Activity (shown at the top of the 331 screen), use the <code>notepad_list</code> layout we created in XML, 332 set up the <code>NotesDbAdapter</code> instance that will 333 access notes data, and populate the list with the available note 334 titles:</p> 335 <ol> 336 <li> 337 In the <code>onCreate</code> method, call <code>super.onCreate()</code> with the 338 <code>savedInstanceState</code> parameter that's passed in.</li> 339 <li> 340 Call <code>setContentView()</code> and pass <code>R.layout.notepad_list</code>.</li> 341 <li> 342 At the top of the class, create a new private class field called <code>mDbHelper</code> of class 343 <code>NotesDbAdapter</code>. 344 </li> 345 <li> 346 Back in the <code>onCreate</code> method, construct a new 347<code>NotesDbAdapter</code> 348 instance and assign it to the <code>mDbHelper</code> field (pass 349 <code>this</code> into the constructor for <code>DBHelper</code>) 350 </li> 351 <li> 352 Call the <code>open()</code> method on <code>mDbHelper</code> to open (or create) the 353 database. 354 </li> 355 <li> 356 Finally, call a new method <code>fillData()</code>, which will get the data and 357 populate the ListView using the helper — we haven't defined this method yet. </li> 358 </ol> 359 <p> 360 <code>onCreate()</code> should now look like this:</p> 361 <pre> 362 @Override 363 public void onCreate(Bundle savedInstanceState) { 364 super.onCreate(savedInstanceState); 365 setContentView(R.layout.notepad_list); 366 mDbHelper = new NotesDbAdapter(this); 367 mDbHelper.open(); 368 fillData(); 369 }</pre> 370 <p>And be sure you have the <code>mDbHelper</code> field definition (right 371 under the mNoteNumber definition): </p> 372 <pre> private NotesDbAdapter mDbHelper;</pre> 373 374 <h2>Step 9</h2> 375 376 <div class="sidebox" style="border:2px solid #FFFFDD;float:right; 377 background-color:#FFFFEE;margin-right:0px; 378 margin-bottom:.5em;margin-top:1em;padding:0em;width:240px;"> 379 <h2 style="border:0;font-size:12px;padding:.5em .5em .5em 1em;margin:0; 380 background-color:#FFFFDD;">More on menus</h2> 381 <p style="padding-left:.5em;font-size:12px;margin:0; 382 padding:.0em .5em .5em 1em;">The notepad application we are constructing only scratches the 383 surface with <a href="{@docRoot}guide/appendix/faq/commontasks.html#addmenuitems">menus</a>. </p> 384 <p style="padding-left:.5em;font-size:12px;margin:0; 385 padding:.0em .5em .5em 1em;">You can also <a href="{@docRoot}guide/appendix/faq/commontasks.html#menukeyshortcuts">add 386shortcut keys for menu items</a>, <a href="{@docRoot}guide/appendix/faq/commontasks.html#menukeyshortcuts">create 387submenus</a> and even <a href="{@docRoot}guide/appendix/faq/commontasks.html#addingtoothermenus">add 388menu items to other applications!</a>. </p> 389 </div> 390 391<p>Fill out the body of the <code>onCreateOptionsMenu()</code> method.</p> 392 393<p>We will now create the "Add Item" button that can be accessed by pressing the menu 394button on the device. We'll specify that it occupy the first position in the menu.</p> 395 396 <ol> 397 <li> 398 In <code>strings.xml</code> resource (under <code>res/values</code>), add 399 a new string named "menu_insert" with its value set to <code>Add Item</code>: 400 <pre><string name="menu_insert">Add Item</string></pre> 401 <p>Then save the file and return to <code>Notepadv1</code>.</p> 402 </li> 403 <li>Create a menu position constant at the top of the class: 404 <pre>public static final int INSERT_ID = Menu.FIRST;</pre> 405 </li> 406 <li>In the <code>onCreateOptionsMenu()</code> method, change the 407 <code>super</code> call so we capture the boolean return as <code>result</code>. We'll return this value at the end.</li> 408 <li>Then add the menu item with <code>menu.add()</code>.</li> 409 </ol> 410 <p>The whole method should now look like this: 411 <pre> 412 @Override 413 public boolean onCreateOptionsMenu(Menu menu) { 414 boolean result = super.onCreateOptionsMenu(menu); 415 menu.add(0, INSERT_ID, 0, R.string.menu_insert); 416 return result; 417 }</pre> 418 <p>The arguments passed to <code>add()</code> indicate: a group identifier for this menu (none, 419 in this case), a unique ID (defined above), the order of the item (zero indicates no preference), 420 and the resource of the string to use for the item.</p> 421 422<h2 style="clear:right;">Step 10</h2> 423 <p>Fill out the body of the <code>onOptionsItemSelected()</code> method:</p> 424 <p>This is going 425 to handle our new "Add Note" menu item. When this is selected, the 426 <code>onOptionsItemSelected()</code> method will be called with the 427 <code>item.getId()</code> set to <code>INSERT_ID</code> (the constant we 428 used to identify the menu item). We can detect this, and take the 429 appropriate actions:</p> 430 <ol> 431 <li> 432 The <code>super.onOptionsItemSelected(item)</code> method call goes at the 433 end of this method — we want to catch our events first! </li> 434 <li> 435 Write a switch statement on <code>item.getItemId()</code>. 436 <p>In the case of <var>INSERT_ID</var>, call a new method, <code>createNote()</code>, 437 and return true, because we have handled this event and do not want to 438 propagate it through the system.</p> 439 </li> 440 <li>Return the result of the superclass' <code>onOptionsItemSelected()</code> 441 method at the end.</li> 442 </ol> 443 <p> 444 The whole <code>onOptionsItemSelect()</code> method should now look like 445 this:</p> 446 <pre> 447 @Override 448 public boolean onOptionsItemSelected(MenuItem item) { 449 switch (item.getItemId()) { 450 case INSERT_ID: 451 createNote(); 452 return true; 453 } 454 455 return super.onOptionsItemSelected(item); 456 }</pre> 457 458<h2>Step 11</h2> 459 <p>Add a new <code>createNote()</code> method:</p> 460 <p>In this first version of 461 our application, <code>createNote()</code> is not going to be very useful. 462We will simply 463 create a new note with a title assigned to it based on a counter ("Note 1", 464 "Note 2"...) and with an empty body. At present we have no way of editing 465 the contents of a note, so for now we will have to be content making one 466 with some default values:</p> 467 <ol> 468 <li>Construct the name using "Note" and the counter we defined in the class: <code> 469 String noteName = "Note " + mNoteNumber++</code></li> 470 <li> 471 Call <code>mDbHelper.createNote()</code> using <code>noteName</code> as the 472 title and <code>""</code> for the body 473 </li> 474 <li> 475 Call <code>fillData()</code> to populate the list of notes (inefficient but 476 simple) — we'll create this method next.</li> 477 </ol> 478 <p> 479 The whole <code>createNote()</code> method should look like this: </p> 480 <pre> 481 private void createNote() { 482 String noteName = "Note " + mNoteNumber++; 483 mDbHelper.createNote(noteName, ""); 484 fillData(); 485 }</pre> 486 487 488<h2>Step 12</h2> 489 <div class="sidebox" style="border:2px solid #FFFFDD;float:right; 490 background-color:#FFFFEE;margin-right:0px; 491 margin-bottom:.5em;margin-top:1em;padding:0em;width:240px;"> 492 <h2 style="border:0;font-size:12px;padding:.5em .5em .5em 1em;margin:0; 493 background-color:#FFFFDD;">List adapters</h2> 494 <p style="padding-left:.5em;font-size:12px;margin:0; 495 padding:.0em .5em .5em 1em;">Our example uses a {@link android.widget.SimpleCursorAdapter 496 SimpleCursorAdapter} to bind a database {@link android.database.Cursor Cursor} 497 into a ListView, and this is a common way to use a {@link android.widget.ListAdapter 498 ListAdapter}. Other options exist like {@link android.widget.ArrayAdapter ArrayAdapter} which 499 can be used to take a List or Array of in-memory data and bind it in to 500 a list as well.</p> 501 </div> 502 503 <p>Define the <code>fillData()</code> method:</p> 504 <p>This 505 method uses <code>SimpleCursorAdapter,</code> which takes a database <code>Cursor</code> 506 and binds it to fields provided in the layout. These fields define the row elements of our list 507 (in this case we use the <code>text1</code> field in our 508 <code>notes_row.xml</code> layout), so this allows us to easily populate the list with 509 entries from our database.</p> 510 <p>To do this we have to provide a mapping from the <code>title</code> field in the returned Cursor, to 511 our <code>text1</code> TextView, which is done by defining two arrays: the first a string array 512 with the list of columns to map <em>from</em> (just "title" in this case, from the constant 513 <code>NotesDbAdapter.KEY_TITLE</code>) and, the second, an int array 514 containing references to the views that we'll bind the data <em>into</em> 515 (the <code>R.id.text1</code> TextView).</p> 516 <p>This is a bigger chunk of code, so let's first take a look at it:</p> 517 518 <pre> 519 private void fillData() { 520 // Get all of the notes from the database and create the item list 521 Cursor c = mDbHelper.fetchAllNotes(); 522 startManagingCursor(c); 523 524 String[] from = new String[] { NotesDbAdapter.KEY_TITLE }; 525 int[] to = new int[] { R.id.text1 }; 526 527 // Now create an array adapter and set it to display using our row 528 SimpleCursorAdapter notes = 529 new SimpleCursorAdapter(this, R.layout.notes_row, c, from, to); 530 setListAdapter(notes); 531 }</pre> 532 533 <p>Here's what we've done:</p> 534 <ol> 535 <li> 536 After obtaining the Cursor from <code>mDbHelper.fetchAllNotes()</code>, we 537 use an Activity method called 538 <code>startManagingCursor()</code> that allows Android to take care of the 539 Cursor lifecycle instead of us needing to worry about it. (We will cover the implications 540 of the lifecycle in exercise 3, but for now just know that this allows Android to do some 541 of our resource management work for us.)</li> 542 <li> 543 Then we create a string array in which we declare the column(s) we want 544 (just the title, in this case), and an int array that defines the View(s) 545 to which we'd like to bind the columns (these should be in order, respective to 546 the string array, but here we only have one for each).</li> 547 <li> 548 Next is the SimpleCursorAdapter instantiation. 549 Like many classes in Android, the SimpleCursorAdapter needs a Context in order to do its 550 work, so we pass in <code>this</code> for the context (since subclasses of Activity 551 implement Context). We pass the <code>notes_row</code> View we created as the receptacle 552 for the data, the Cursor we just created, and then our arrays.</li> 553 </ol> 554 <p> 555 In the future, remember that the mapping between the <strong>from</strong> columns and <strong>to</strong> resources 556 is done using the respective ordering of the two arrays. If we had more columns we wanted 557 to bind, and more Views to bind them in to, we would specify them in order, for example we 558 might use <code>{ NotesDbAdapter.KEY_TITLE, NotesDbAdapter.KEY_BODY }</code> and 559 <code>{ R.id.text1, R.id.text2 }</code> to bind two fields into the row (and we would also need 560 to define text2 in the notes_row.xml, for the body text). This is how you can bind multiple fields 561 into a single row (and get a custom row layout as well).</p> 562 <p> 563 If you get compiler errors about classes not being found, ctrl-shift-O or 564 (cmd-shift-O on the mac) to organize imports. 565 </p> 566 567<h2 style="clear:right;">Step 13</h2> 568 <p>Run it! 569 <ol> 570 <li> 571 Right click on the <code>Notepadv1</code> project.</li> 572 <li> 573 From the popup menu, select <strong>Run As</strong> > 574 <strong>Android Application</strong>.</li> 575 <li> 576 If you see a dialog come up, select Android Launcher as the way of running 577 the application (you can also use the link near the top of the dialog to 578 set this as your default for the workspace; this is recommended as it will 579 stop the plugin from asking you this every time).</li> 580 <li>Add new notes by hitting the menu button and selecting <em>Add 581 Item</em> from the menu.</li> 582 </ol> 583 584<h2 style="clear:right;">Solution and Next Steps</h2> 585 <p>You can see the solution to this class in <code>Notepadv1Solution</code> 586from 587the zip file to compare with your own.</p> 588 589<p>Once you are ready, move on to <a href="notepad-ex2.html">Tutorial 590Exercise 2</a> to add the ability to create, edit and delete notes.</p> 591 592