Creating the Application’s Screens

The Task Reminder application needs two different screens to perform all its basic functions: create, read, update, and delete (CRUD) tasks:

check.png One view lists all current tasks in the application. This view also allows the user to delete a task by long-pressing the item.

check.png A view to allow the user to view (read), add (create), or edit (update) a task.

Each screen eventually interacts with a database for changes to be persisted over the long-term use of the application.

Each screen consists of a single code fragment that contains most of the user interface for the screen, and that fragment is contained in an activity.

tip.eps You can reuse fragments if — or when — you build tablet support into your app. See Part IV for tablet development.

Starting the new project

To get started, open Eclipse and create a new Android project with a valid name, package, and activity. Table 9-1 shows the Eclipse settings for the Task Reminder app. (If you’re unfamiliar with how to create an Android project, see Chapter 3.)

If you download the source code from this book’s website, you can also open the Chapter 9 Android project example.

Table 9-1 New Project Settings

Property

Value

Project Name

Task Reminder

Build Target

Android 4.0.3 (API Level 15)

Application Name

Task Reminder

Package Name

com.dummies.android. taskreminder

Create Activity

ReminderListActivity

Min SDK Version

4

Note the Create Activity property value — ReminderListActivity. Normally, you give the first activity in an application the name of MainActivity; however, the first screen the user sees in the Task Reminder app is a list of current tasks. Therefore, this activity is an instance of a ListActivity; hence the name ReminderListActivity.

The Task Reminder app uses features from the Android Support Library to support devices running Android 2.x and earlier. Add the library to your Eclipse project by following these steps:

1. Copy the android-support-v13.jar file to your project’s libs directory.

It’s in ANDROID_SDK/extras/android/support/v13.

tip.eps If you can’t find the android-support-v13.jar file in your Android SDK directory, you may not have installed the support library yet. Open the Android SDK Manager and click Extras to install the support library from there.

2. Choose ProjectClean from the Eclipse menu.

Once the project finishes rebuilding, your Android Dependencies listing should look like the one shown in Figure 9-1.

Figure 9-1: The android-support-v13.jar file in your project listing.

9781118417454-fg0901.eps

Creating the ReminderListActivity

The ReminderListActivity class that Eclipse generated for you is practically empty so you’ll want to make some changes to it. Do the following:

check.png Rename the activity_main.xml file to reminder_list.xml . Eclipse starts your project with the activity_main.xml file, located in the res/layout directory. To make it easy to find your layout file when you open the directory, rename it to something more informative. To rename the activity_main.xml file, right-click it and choose Refactor⇒Rename or select the file and press Shift+Alt+R.

check.png Update the Java file. After you change the filename, you need to update the name of the file in the setContentView() call inside the ReminderListActivity.java file. Open the file and replace R.layout.activity_main with R.layout.reminder_list.

check.png Change the inheritance. Because the ReminderListActivity contains fragments, it needs to inherit from the FragmentActivity class instead of the regular base activity. Make that change, too.

Your new ReminderListActivity class now looks like Listing 9-1.

Listing 9-1: The ReminderListActivity Class

public class ReminderListActivity extends FragmentActivity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.reminder_list);

}

}

setContentView() uses the reminder_list layout file, but you haven’t defined that yet. Open the res/layout/reminder_list.xml file and update it to look like Listing 9-2.

Listing 9-2: The reminder_list.xml Contents

<?xml version=”1.0” encoding=”utf-8”?>

<fragment

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

android:name=”com.dummies.android.taskreminder.ReminderListFragment”

android:layout_width=”fill_parent”

android:layout_height=”fill_parent” />

The layout file for your activity has only a single element in it, the ReminderListFragment, which takes up the full height and width of the screen. The ReminderListFragment does all the hard work to display the list of tasks to the user.

Creating the ReminderListFragment

Fragments are the parts of your activities that are meant to be re-used throughout your application. Most activities have one or two fragments. The list activity needs a fragment to display the list of tasks, so create a new file named ReminderListFragment and copy the code in Listing 9-3.

Listing 9-3: The ReminderList Fragment

package com.dummies.android.taskreminder;

import android.os.Bundle;

import android.support.v4.app.ListFragment; →4

import android.view.View;

public class ReminderListFragment extends ListFragment {

@Override

public void onActivityCreated(Bundle savedInstanceState) { →10

super.onActivityCreated(savedInstanceState);

setEmptyText(getResources().getString(R.string.no_reminders)); →12

}

}

technicalstuff.eps

Here’s a brief explanation of the code in Listing 9-3:

4 This line ensures that you’re using the android.support.v4.app.* imports and not their equivalents from android.app.

remember.eps Import android.support.v4.app.Fragment and android.support.v4.app.FragmentTransaction, and not their equivalents from android.app. Using the android.support.v4.* classes from the Android Support Library ensures that your application works on devices with Android versions going back to v4 (Android 1.6). If you don’t care about versions of Android before 3.x, feel free to skip the support library.

10 The activity’s (not the fragment’s) onCreate() method returns and calls the onActivityCreated() callback.

If you need to do anything with your fragment’s views, onActivity Created() is a great place to do it because your fragment’s views are guaranteed to be fully constructed at that point.

12 The ListFragment supports showing a message when the list is empty. The call uses a value of setEmptyText(), and the message uses a value of R.string.no_reminders.

Add <string name=”no_reminders”>No Reminders Yet</string> to your strings.xml file. See Chapter 6 for more information about adding strings to your strings.xml file.

Using an activity to create and edit reminders

The Task Reminder application needs an additional screen that allows the user to edit a task and its information. This new activity and fragment will allow users to create, read, and update tasks.

In Eclipse, follow these steps:

1. Create a new activity that can handle the create, read, and update roles.

Right-click the package name in the src folder and choose New⇒Class, or press Shift+Alt+N and then choose Class. Name it ReminderEditActivity.

2. In the new Java class window, set the superclass to android. support.v4.app.FragmentActivity and click Finish.

A new activity class file opens.

3. Replace the contents of the activity class file with Listing 9-4.

This code creates the activity, sets its content view, and then sets up the fragment for the activity.

Listing 9-4: ReminderEditActivity

package com.dummies.android.taskreminder;

import android.os.Bundle;

import android.support.v4.app.Fragment; →3

import android.support.v4.app.FragmentActivity;

import android.support.v4.app.FragmentTransaction;

public class ReminderEditActivity extends FragmentActivity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.reminder_edit_activity); →11

Fragment fragment = getSupportFragmentManager().findFragmentByTag(

ReminderEditFragment.DEFAULT_EDIT_FRAGMENT_TAG); →15

if (fragment == null) { →17

fragment = new ReminderEditFragment();

Bundle args = new Bundle();

args.putExtra(ReminderProvider.COLUMN_ROWID, getIntent()

.getLongExtra(ReminderProvider.COLUMN_ROWID, 0L)); →21

fragment.setArguments(args); →22

FragmentTransaction transaction = getSupportFragmentManager()

.beginTransaction(); →25

transaction.add(R.id.edit_container, fragment,

ReminderEditFragment.DEFAULT_EDIT_FRAGMENT_TAG); →27

transaction.commit(); →28

}

}

}

Here’s a brief explanation of the code in Listing 9-4:

3 This line ensures you’re using the android.support.v4.app.* imports and not their equivalents from android.app.

11 This line sets the layout for this fragment. Listing 9-5 shows the code for the R.layout.reminder_edit_activity.

15 Before a fragment is added for the first time, this line checks to see whether one is already there.

remember.eps If an activity was re-created from another activity — say, after a screen rotation — the previous fragment would have also been re-created, and that one is used instead of creating one from scratch.

17 If the activity couldn’t find a previous fragment, this line creates a new fragment.

21 Intents can have extras, which allow activities to pass information from one to another. In line 21, the intent uses getLongExtra() to retrieve the long named COLUMN_ROWID if it’s there. If it’s not, the intent uses the value 0L (or 0 as a long).

22 Fragments need arguments. Unlike with normal Java classes, you can’t pass arguments to a fragment via a constructor. Instead, line 22 uses a bundle named Fragment.setArguments().

25 Any time you want to interact with a fragment, you must use a FragmentTransaction. This line calls FragmentActivity.getSupportFragmentManager() to get the FragmentManager, and from there calls FragmentManager.beginTransaction() to start a transaction. All fragments operate between the Fragment Transaction.beginTransaction() and Fragment Transaction.commit() calls.

27 This line adds the fragment to the activity. It places the fragment in a FrameLayout placeholder named R.id.edit_container (which you define in Listing 9-5) and names it DEFAULT_EDIT_FRAGMENT_TAG so that the app can find it again by that name.

28 This line finishes the transaction.

tip.eps You may notice that the fragment is set up differently in this class than for the ReminderListActivity class. In ReminderListActivity, the <fragment> element is added directly to the XML because the fragment needed no parameters. The ReminderEditFragment activity needs the fragment to be manually added by using Java code to pass the reminder ID.

The reminder_edit_activity.xml layout file shown in Listing 9-5 consists of a single full-screen placeholder element called edit_container that the Java code in Listing 9-1 uses to attach the ReminderListFragment.

Listing 9-5: R.layout.reminder_edit_activity

<?xml version=”1.0” encoding=”utf-8”?>

<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”

android:layout_width=”fill_parent”

android:layout_height=”fill_parent”>

<FrameLayout

android:id=”@+id/edit_container”

android:layout_width=”fill_parent”

android:layout_height=”fill_parent”

/>

</LinearLayout>

The ReminderEditActivity uses a constant in a class called ReminderProvider which doesn’t exist yet, so create that class now and edit it to look like the following:

package com.dummies.android.taskreminder;

public class ReminderProvider {

public static final String COLUMN_ROWID = “_id”;

}

You also need to inform the Android platform about the existence of the ReminderEditActivity by adding it to the Android Manifest. You can do so by adding it to the Application element of the AndroidManifest.xml file, as shown here in bold:

<application android:icon=”@drawable/ic_launcher” android:label=”@string/app_name”>

<activity android:name=”.ReminderListActivity”

android:label=”@string/app_name”>

<intent-filter>

<action android:name=”android.intent.action.MAIN” />

<category android:name=”android.intent.category.LAUNCHER” />

</intent-filter>

</activity>

<activity android:name=”.ReminderEditActivity”

android:label=”@string/app_name” />

</application>

warning_bomb.eps If you don’t add the activity to the AndroidManifest.xml file, you receive a runtime exception informing you that Android cannot find the class (the activity).

Adding a fragment to the activity

After you’ve created an activity to hold the ReminderEditFragment, it’s time to create the fragment. Create a new Java class, name it ReminderEditFragment, and copy the following code into the file:

package com.dummies.android.taskreminder;

import android.os.Bundle;

import android.support.v4.app.Fragment; →4

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.Button;

import android.widget.EditText;

public class ReminderEditFragment extends Fragment {

public static final String DEFAULT_EDIT_FRAGMENT_TAG = “editFragmentTag”; →12

private EditText mTitleText;

private EditText mBodyText;

private Button mDateButton;

private Button mTimeButton;

private Button mConfirmButton;

private long mRowId; →19

@Override

public void onCreate(Bundle savedInstanceState) { →22

super.onCreate(savedInstanceState);

Bundle arguments = getArguments(); →25

if (arguments != null) {

mRowId = arguments.getLong(ReminderProvider.COLUMN_ROWID);

}

}

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) { →33

View v = inflater.inflate(R.layout.reminder_edit, container, false); →35

mTitleText = (EditText) v.findViewById(R.id.title);

mBodyText = (EditText) v.findViewById(R.id.body);

mDateButton = (Button) v.findViewById(R.id.reminder_date);

mTimeButton = (Button) v.findViewById(R.id.reminder_time);

mConfirmButton = (Button) v.findViewById(R.id.confirm);

return v;

}

}

Here’s how the code works:

4 Make sure you’re using the android.support.v4.app.* imports and not their equivalents from android.app.

12 Activities need a tag or an ID to refer to when they work with fragments. This line gives the ReminderEditFragment a tag so it can be found again later using the same tag.

19 Every instance of ReminderEditFragment has an ID for the reminder. The Row ID corresponds to a row in the database. When editing existing reminders, mRowId is the ID of the row in the database for that reminder. New reminders get a mRowId of 0.

22 Fragments have onCreate() methods, just as activities do. onCreate() is called when the fragment is created, and you generally do most of the fragment initialization in onCreate.

Unlike with activities, though, you don’t do initialization related to views in onCreate. Those have to wait until onCreateView() on line 33.

25 The fragment finds out which reminder the user is editing or creating by calling getArguments().

remember.eps Arguments come from the bundle that’s returned by get Arguments(), not from the bundle that’s passed into on Create() (an easy mistake to make).

33 Unlike with activities, you inflate your XML layouts in Fragment.onCreateView() instead of using Activity.setContent View(). This line inflates R.layout.reminder_edit layout, and then calls findViewById() to set up the View objects, much like you would do when initializing an activity.

You could set up the View objects in onActivityCreated(), but it’s convenient to do so in onCreateView() in this case because you’re not manipulating views. See the sidebar “The fragment lifecycle” for more information about onActivity Created() versus onCreateView().

35 This line calls inflate() with attachToRoot set to false, because the fragment attaches the view.

Creating the adding/editing fragment layout

The layout for adding and editing is fairly simple because the form contains only a few fields:

check.png Title: The title of the task as it will show in list view

check.png Body: The body of the task, where the user would type details

check.png Reminder Date: The date on which the user should be reminded of the task

check.png Reminder Time: The time at which the user should be reminded on the reminder date

When the app is complete and running on a device or an emulator, the screen looks like Figure 9-2.

Figure 9-2: The Add/Edit Task Reminder screen.

9781118417454-fg0902.tif

To create this layout, create a layout file in the res/layout directory with an appropriate name; for example, reminder_edit.xml. To create this file, follow these steps:

1. Right-click the res/layout directory and choose NewAndroid XML File.

2. Provide the name in the File field.

3. Leave the default type of resource selected — Layout.

4. Leave the folder set to res/layout .

5. Set the root element to ScrollView .

6. Click the Finish button.

You now need to provide all view definitions to build the screen. (Refer to Figure 9-2.) To do this, type the code shown in Listing 9-6.

Listing 9-6: The reminder_edit.xml File

<?xml version=”1.0” encoding=”utf-8”?>

<ScrollView

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

android:layout_width=”fill_parent”

android:layout_height=”fill_parent”> →5

<LinearLayout →6

android:orientation=”vertical” →7

android:layout_width=”fill_parent”

android:layout_height=”fill_parent”>

<TextView android:layout_width=”wrap_content”

android:layout_height=”wrap_content”

android:text=”@string/title” /> →12

<EditText android:id=”@+id/title”

android:layout_width=”fill_parent”

android:layout_height=”wrap_content” /> →15

<TextView android:layout_width=”wrap_content”

android:layout_height=”wrap_content”

android:text=”@string/body” /> →18

<EditText android:id=”@+id/body”

android:layout_width=”fill_parent”

android:layout_height=”wrap_content”

android:minLines=”5”

android:scrollbars=”vertical”

android:gravity=”top” /> →24

<TextView android:layout_width=”wrap_content”

android:layout_height=”wrap_content”

android:text=”@string/date” /> →27

<Button

android:id=”@+id/reminder_date”

android:layout_height=”wrap_content”

android:layout_width=”wrap_content”/> →31

<TextView android:layout_width=”wrap_content”

android:layout_height=”wrap_content”

android:text=”@string/time” /> →34

<Button

android:id=”@+id/reminder_time”

android:layout_height=”wrap_content”

android:layout_width=”wrap_content” /> →38

<Button android:id=”@+id/confirm”

android:text=”@string/confirm”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content” /> →42

</LinearLayout>

</ScrollView>

Here’s brief explanation of the code in Listing 9-6:

5 The parent view is ScrollView, which creates a scroll bar and allows the view to be scrolled when the contents of the view are too large to fit onscreen. The screen shown in Figure 9-2 is shown in Portrait mode. However, if the device is rotated 90 degrees, the view flips and more than half is cut off. The parent ScrollView allows the remaining contents of the screen to be scrollable. Therefore, the user can flick a finger upward on the screen to scroll the contents and see the remainder of the view.

6 A ScrollView can have only one child — in this case, the main LinearLayout that houses the rest of the layout.

7 The orientation of the linear layout is set to vertical to signify that the views inside this layout should be stacked on top of one another.

12 This is the label for the Title field.

15 The EditText that allows the user to provide a title for the task. You add <string name=”title”>Title</string> to strings.xml.

18 The label for the Body field and add the <string name=”body”>Body</string> to the strings.xml.

24 The EditText that defines the Body field. The EditText view has set the minLines property to 5 and the gravity property to top to inform the Android platform that the EditText is at least five lines tall and that when the user starts typing, the text should be bound to the top of the view (the gravity).

27 The reminder date label also uses a string resource. You need to add a string resource with the name of “date” and a value of “Reminder Date”.

31 When this reminder date button is tapped, a DatePickerDialog is launched. The user can choose a date with a built-in Android date picker. When the date is set via the DatePicker, the value of the date is set as the button text.

34 This reminder time label uses a string resource. You need to add a string resource with the name of “time” and a value of “Time”.

38 When this time reminder button is clicked, a TimePicker is launched. The user can choose a time with a built-in Android time picker. When the time is set via the TimePickerDialog, the value of the time is set as the button text.

42 This confirmation button saves the values of the form when clicked. Add <string name=”confirm”>Save</string> to the strings.xml.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset