エクササイズ1

「エクササイズ1」の編集履歴(バックアップ)一覧に戻る
エクササイズ1」を以下のとおり復元します。
Tutorial: Notepad Exercise 1

In this exercise, you will construct a simple notes list that lets the user add new notes but not edit them. The exercise demonstrates:

    * The basics of ListActivities and creating and handling menu options.
    * How to access/store the notes in an SQLite database to store the notes.
    * How to bind data into a ListView using an ArrayAdapter (one of the simplest ways to bind to a ListView).
    * The basics of screen layouts, including how to lay out a list view, how you can add items to the activity menu, and how the activity handles those menu selections.

[Exercise 1] [Exercise 2] [Exercise 3] [Extra Credit]
Step 1

Open up the Notepadv1 project in Eclipse.

Notepadv1 is a project that is provided as a starting point - it takes care of some of the boilerplate work that you have already seen if you followed the Hello Android tutorial.

   1. Right click in the Package Explorer, select Import.../General/Existing Projects into Workspace.
   2. Hit the browse button, and navigate to where you copied the three exercise folders, select Notepadv1 and hit OK.
   3. You should see Notepadv1 listed in the projects with a check mark next to it.
   4. Hit Finish.
   5. The exercise project should be open and ready to go in your Eclipse package explorer.
   6. If you see an error about AndroidManifest.xml, or some problems related to an Android zip file, right click on the project and select Android Tools->Fix Project Properties from the popup menu (the project is looking in the wrong location for the library file, this will fix it for you).

Step 2
Accessing and modifying data

For this exercise, we are just going to use a SQLite database directly to store our data, but in a real application it would be much better to write a proper ContentProvider to encapsulate this behavior instead.

If you are interested, you can find out more about content providers or the whole subject of Storing, Retrieving, and Exposing Data.

Take a look at the DBHelper class — this class is provided to encapsulate data access to a SQLite database that will hold our notes data and allow us to update it.

Typically you would implement this using a ContentProvider, and in fact the full Notepad application included with the SDK does implement such a ContentProvider. However, there is no reason you can't just use your own SQLite database directly as we do here. The main thing to notice about this class is that it takes care of the details of storing, retrieving and updating data in the SQLite database for us. There are methods for retrieving all the rows, retrieving a row based on rowIds, creating a new row, deleting an existing row and updating a row. If you want a quick primer in how to use the SQLite Database for your own applications, either take a look at this class or better yet, look at the full Notepad application included with the SDK in the samples/ folder as the sample uses a ContentProvider.
Step 3
Layouts and activities

Most Activities will have a layout associated with them. The layout will be the "face" of the activity to the user. In this case our layout will take over the whole screen and provide a list of notes.

Full screen layouts are not the only option for an Activity however. You might also want to use a floating layout (for example, a dialog or alert), or perhaps you don't need a layout at all (the activity will be invisible to the user unless you specify some kind of layout for it to use).

Open the notepad_list.xml file in res/layout and take a look at it:

This is a layout definition file with a default starting point in it, we have provided this as a convenience to get you going quickly.

   1. All Android layout files must start with the XML header line: <?xml version="1.0" encoding="utf-8"?>.
   2. Also, the next definition will often (but not always) be a layout definition of some kind, in this case a LinearLayout.
   3. Note also that the xml namespace of Android should always be defined in the top level component or layout in the XML so that android: tags can be used through the rest of the file:

      xmlns:android="http://schemas.android.com/apk/res/android"

Step 4

We need to create the layout to hold our list. Add code inside of the LinearLayout tag so the whole file looks like this: (you may have to hit the Source tab in order to edit the XML file)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

  <ListView id="@id/android:list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
  <TextView id="@id/android:empty"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/no_notes"/>

</LinearLayout>

   1. The ListView and TextView can be thought as two alternative views, only one of which will be displayed at once. ListView will be used when there are notes to be shown, while the TextView (which has a default value of "No Notes Yet!" defined as a string resource, will be displayed if there aren't any notes to display).
   2. The @ in the id strings of the ListView and TextView means that the XML parser should parse and expand the rest of the id string and use an ID resource.
   3. And, the android:list and android:empty are IDs that are already provided for us by the Android platform, empty is used automatically when no data is provided in the list adapter. The List Adapter knows to look for these names specifically by default. Alternatively you could also choose to change the default empty view used by the List Adapter by using the setEmptyView().
      More broadly, the android.R class is a set of predefined resources provided for you by the platform, while your project's R class is the set of resources your project has defined. Resources found in the android.R resource class can be used in the XML files by using the android: name space prefix (as we see here).

Step 5
Resources and the R class

The folders under res/ in the Eclipse project are special. There is a specific structure to the folders and files under this folder.

In particular, resources defined in these folders and files will have corresponding entries in the R class allowing them to be easily accessed and used from your application. Furthermore, they will be bundled and deployed as part of the application.

To make a list view, we also need to define a view for each row in the list:

   1. Create a new file under res/layout called notes_row.xml.
   2. Add the following contents (note: again the xml header is used, and the first node defines the Android xml namespace)

      <?xml version="1.0" encoding="utf-8"?>
      <TextView id="@+id/text1"
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"/>
            

   3. This is the view that will be used for each notes title row — it has only one text field in it.
   4. In this case we create a new id called text1. The + after the @ in the id string indicates that the id should be automatically created if it does not already exist, so we are defining text1 on the fly and then using it.
   5. After saving this file, open the R.java class in the project and look at it, you should see new definitions for notes_row and text1 (our new definitions) meaning we can now gain access to these from the our code.

Step 6

Next, open the Notepadv1 class in the source. We are going to alter this class to become a list adapter and display our notes, and also allow us to add new notes

Notepadv1 will be a subclass of Activity called a ListActivity, which has extra functionality to accommodate the kinds of things you might want to do with a list, for example: displaying an arbitrary number of list items in rows on the screen, moving through the list items, and allowing them to be selected.

Take a look through the existing code in Notepadv1 class. There are some constant definitions at the top, followed by a private field we will use to create numbered note titles, and some overrides of methods from the superclass.
Step 7

Change the inheritance of Notepadv1 from Activity to ListActivity:

public class Notepadv1 extends ListActivity

Note: you will have to import ListActivity into the Notepadv1 class using Eclipse, ctrl-shift-O on Windows or Linux, or cmd-shift-O on the Mac (organize imports) will do this for you.
Step 8

There are already three override methods defined: onCreate, onCreateOptionsMenu and onOptionsItemSelected, we need to fill these out:

    * onCreate() is called when the activity is started — it is a little like the "main" method for the activity. We use this to set up resources and state for the activity when it is running
    * onCreateOptionsMenu() is used to populate the menu for the activity. This is shown when the user hits the menu button, and has a list of options they can select (like "Create Note")
    * onOptionsItemSelected() is the other half of the menu equation, it is used to handle events generated from the menu (e.g. when the user selects the "Create Note" item).

Step 9

Fill out the body of the onCreate() method.

Here we will set the title for the activity (shown at the top of the screen), use the notepad_list layout we have created for the activity display contents, set up the DBHelper instance we will use to access notes data, then populate the list with the available note titles:

   1. call super() with the icicle parameter passed into our method
   2. setContentView to R.layout.notepad_list
   3. Create a new private class field called dbHelper of class DBHelper (before the onCreate method)
   4. Back in the onCreate method, construct a DBHelper instance — assign to the dbHelper field (note, you must pass this into the constructor for DBHelper)
   5. Finally, call a new method -fillData()- gets the data and populates it using the helper, we haven't defined it yet
   6. onCreate() should now look like this:

          @Override
          public void onCreate(Bundle icicle)
          {
              super.onCreate(icicle);
              setContentView(R.layout.notepad_list);
              dbHelper = new DBHelper(this);
              fillData();
          }

      And remember to add the DBHelper field definition (right under the noteNumber definition):

          private DBHelper dbHelper;

Step 10
More on menus

The notepad application we are constructing only scratches the surface with menus.

You can also add shortcut keys for menu items, create submenus and even add menu items to other applications!.

Fill out the body of the onCreateOptionsMenu() method.

We are going to add just one menu item for now, "Add Item", using a string we will create in strings.xml, and defined with a constant we will create at the top of the class to identify the Add Item operation.

   1. In strings.xml resource (under res/values), add a new string for menu_insert with text "Add Item"

      <string name="menu_insert">Add Item</string>, then save the file
   2. Also, you need a menu position constant at the top of the Notepadv1 class (right under the KEY_BODY definition):

      public static final int INSERT_ID = Menu.FIRST;
   3. In the onCreateOptionsMenu() method, add the menu item. Also take care of the result of the super call being returned. The whole method should now look like this:

          @Override
          public boolean onCreateOptionsMenu(Menu menu) {
              boolean result = super.onCreateOptionsMenu(menu);
              menu.add(0, INSERT_ID, R.string.menu_insert);
              return result;
          }
            

Step 11

Fill out the body of the onOptionsItemSelected() method:

This is going to handle our new "Add Note" menu item. When this is selected the onOptionsItemSelected() method will be called with the item.getId() set to INSERT_ID (the constant we used to identify the menu item). We can detect this, and take the appropriate actions:

   1. The super.onOptionsItemSelected(item) method call goes at the end of this method — we want to catch our events first!
   2. Switch statement on item.getId()
   3. case INSERT_ID:
   4. calls new method createNote()
   5. break at the end of the case
   6. return the result of the superclass onOptionsItemSelected() method at the end
   7. The whole onOptionsItemSelect() method should now look like this:

          @Override
          public boolean onOptionsItemSelected(Item item) {
              switch (item.getId()) {
              case INSERT_ID:
                  createNote();
                  break;
              }
             
              return super.onOptionsItemSelected(item);
          }
          

Step 12

Add a new createNote() method:

In this first version of our application, createNote() is not going to be very useful. We will simply create a new note with a title assigned to it based on a counter ("Note 1", "Note 2"...) and with an empty body. At present we have no way of editing the contents of a note, so for now we will have to be content making one with some default values:

   1. String noteName = "Note " + noteNumber++; (Construct the name using "Note" and the counter we have defined in the class)
   2. Call dbHelper.createRow() using noteName as the title and "" for the body
   3. Call fillData() method again after adding (inefficient but simple)
   4. The whole createNote() method should look like this:

          private void createNote() {
              String noteName = "Note " + noteNumber++;
              dbHelper.createRow(noteName, "");
              fillData();
          }
            

Step 13
List adapters

Our example uses a very simple array adapter which binds an array or list of items into a ListView. More commonly in Android, List Adapters go hand in hand with ContentProviders, and this is also a very easy way to use lists.

To bind a ContentProvider to a ListView you can use a android.widget.SimpleCursorAdapter to bind data from a ContentProvider into a ListView

Define the fillData() method. This is fairly long:

This method uses ArrayAdapter, which is the simplest way of putting data into a ListView. ArrayAdapter takes either a List or an array of Strings, and binds them into a text view provided in the layout defined for the list row (this is the text1 field in our notes_row.xml layout). The method simply obtains a list of notes from the database helper, constructs a List of Strings using the title strings from each row, and then creates an ArrayAdapter out of those items and bound to use the notes_row we defined.

    private void fillData() {
        // We need a list of strings for the list items
        List<String> items = new ArrayList<String>();

        // Get all of the rows from the database and create the item list
        List<Row> rows = dbHelper.fetchAllRows();
        for (Row row : rows) {
            items.add(row.title);
        }
        
        // Now create an array adapter and set it to display using our row
        ArrayAdapter<String> notes =
            new ArrayAdapter<String>(this, R.layout.notes_row, items);
        setListAdapter(notes);
        
    }

   1. ArrayAdapter needs a List of Strings (List<String>) containing the items to display
   2. The data is read out of the database as rows, and the title field from each row is used to populate the list of strings
   3. We specify the notes_row view we created as the receptacle for the data
   4. If you get compiler errors about classes not being found, ctrl-shift-O or (cmd-shift-O on the mac) to organize imports.

Note: that for this exercise we use an ArrayAdapter, this is not a very scalable solution and more typically a SimpleCursorAdapter would be used with a ContentProvider or at least a Cursor returned from a query. See the sidebar on List Adapters for more information.
Step 14

Run it!

   1. Right click on the Notepadv1 project
   2. From the popup menu, select Run As -> Android Application
   3. If you see a dialog come up, select Android Launcher as the way of running the application (you can also use the link near the top of the dialog to set this as your default for the workspace, this is recommended as it will stop the plugin from asking you this every time)
   4. Add new notes by hitting the menu button and selecting Add Item from the menu

Solution and Next Steps

You can see the solution to this class in Notepadv1Solution from the zip file to compare with your own.

Once you are ready, move on to Tutorial Exercise 2 to add the ability to create, edit and delete notes.

Back to the Tutorial main page...

復元してよろしいですか?

ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。