Getting Choosy with Dates and Times

What would your Task Reminder application be without a way to set the date and time for the reminder? Well, it wouldn't be a Task Reminder application at all! It would simply be a Task List application — and that's kind of boring if you ask me.

If you've done any programming with dates and times in other programming languages, you know that building a mechanism for a user to enter a date and a time can be a painstaking process all in itself. However, I'm happy to report that the Android platform has relieved Android programmers of this difficulty. The Android platform provides two classes that assist you in this process — the DatePicker and TimePicker — and these pickers also provide built-in classes that allow you to pop up a dialog box so that the user can select a date and a time. This means you have the option to either embed the DatePicker or TimePicker into your application's views or to use the Dialog classes, which saves you the process of creating a view in which to contain the DatePicker and TimePicker views.

Enough jibber-jabber about what the picker widgets can do. I'm sure you're ready to start using them!

Creating picker buttons

You have not added the DatePicker or TimePicker to the Task Reminder application yet, but you do so in this section. Part of the reminder_edit.xml file contains mechanisms to help display the DatePicker and TimePicker. These mechanisms are located after the EditText definitions discussed earlier in this chapter — two buttons with two labels above them, as shown in Listing 13-1. Please add this code to your reminder_edit.xml file now.

Listing 13-1: The Date and Time Buttons with Their Corresponding TextView Labels

<TextView android:layout_width=“wrap_content”                        →1
    android:layout_height=“wrap_content”
    android:text=“@string/date” />
<Button                                                              →4
    android:id=“@+id/reminder_date”
    android:layout_height=“wrap_content”
    android:layout_width=“wrap_content”
    />
<TextView android:layout_width=“wrap_content”                        →9
    android:layout_height=“wrap_content”
    android:text=“@string/time” />
<Button                                                             →12
    android:id=“@+id/reminder_time”
    android:layout_height=“wrap_content”
    android:layout_width=“wrap_content”
    />

The code lines are explained here:

→1 This line is the TextView label for the Date button. This displays the value of ReminderDate according to the string resource.
→4 This line defines a button that the user clicks to open the DatePickerDialog, as explained in the next section, “Wiring up the date picker.”
→9 This line is the TextView label for the Time button. This displays the value of ReminderTime according to the string resource.
→12 This line defines a button that the user clicks to open the TimePickerDialog, as explained in the next section, “Wiring up the date picker.”.

Wiring up the date picker

When the user clicks the Date button, he should be able to edit the date. To do this, you need to declare the onClickListener() for the Date button, and then, when a click is detected, open a dialog box that allows the user to make the change. I show you how to do this in the following sections.

Setting up the Date button click listener

To implement this functionality, open the activity where your code is to be placed — for the Task Reminder application, open the ReminderEditActivity.java file.

In the onCreate() method, type the following code:

registerButtonListenersAndSetDefaultText();

Eclipse informs you that you need to create the method, so do that now. The easiest way to do this is by hovering your cursor over the method call's squiggly and choosing from the resulting context menu the “Create method ‘registerButtonListenersAndSetDefaultText()’” option. In the registerButtonListenersAndSetDefaultText() method, type the code shown in Listing 13-2.

Listing 13-2: Implementing the Date Button Click Listener

mDateButton.setOnClickListener(new View.OnClickListener() {          →1

    @Override
    public void onClick(View v) {                                    →4
           showDialog(DATE_PICKER_DIALOG);                           →5
    }
});
updateDateButtonText();                                              →8
updateTimeButtonText();                                              →9

This code is explained as follows:

→1 This line uses the mDateButton variable. As you have probably noticed, you have not defined this variable anywhere. You need to define this variable at the top of the class file. After this variable is defined, you can set the onClickListener() for the button. The onClickListener() is what executes when the button is clicked. The action that takes place on the button click is shown on line 5.
private Button mDateButton;

After this variable is created, you need to initialize it in the onCreate() method (right after the call to setContentView()):

mDateButton = (Button) findViewById(R.id.reminder_date);
→4 This line overrides the default click behavior of the button so that you can provide your own set of actions to perform. The View v parameter is the view that was clicked.
→5 This line defines what you want to happen when the button is clicked. In this instance, you call a method on the base activity class — showDialog(). The showDialog() method accepts one parameter — the ID of the dialog box that you want to show — in this case, a constant called DATE_PICKER_DIALOG. This is the first of two constants you must define at the top of the class file by typing the following code. (The second constant is used in the section, “Wiring up the time picker,” later in this chapter.)
private static final int DATE_PICKER_DIALOG = 0;
private static final int TIME_PICKER_DIALOG = 1;
→8 This method is called to update the button text of the date and time buttons. This method is created in Listing 13-5.
→9 This method is called to update the time button text. This method is created in Listing 13-6.

Creating the showDialog() method

The showDialog() method performs some work for you in the base activity class, and at the end of the day, the only thing you need to know is that by calling showDialog() with an ID, the activity's onCreateDialog() method is called. At the bottom of your ReminderEditActivity file, type the code from Listing 13-3 to respond to the showDialog() method call.

Listing 13-3: Responding to showDialog() with onCreateDialog()

@Override
protected Dialog onCreateDialog(int id) {                                                                                                                 →2
    switch(id) {
       case DATE_PICKER_DIALOG:                                                                                                                           →4
         return showDatePicker();
    }
    return super.onCreateDialog(id);
}

private DatePickerDialog showDatePicker() {                                                                                                              →10
    DatePickerDialog datePicker = new DatePickerDialog(ReminderEditActivity.this, new DatePickerDialog.OnDateSetListener() {                             →13

            @Override
            public void onDateSet(DatePicker view, int year, int monthOfYear,
                   int dayOfMonth) {                                                                                                                     →17

            mCalendar.set(Calendar.YEAR, year);                                                                                                          →19
            mCalendar.set(Calendar.MONTH, monthOfYear);
            mCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);                                                                                            →21
            updateDateButtonText();                                                                                                                      →22
            }
    }, mCalendar.get(Calendar.YEAR), mCalendar.get(Calendar.MONTH),
               mCalendar.get(Calendar.DAY_OF_MONTH));                                                                                                    →25
    return datePicker;                                                                                                                                   →26
}

private void updateDateButtonText() {                                                                                                                    →29
    SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);                                                                                     →30
    String dateForButton = dateFormat.format(mCalendar.getTime());                                                                                       →31
    mDateButton.setText(dateForButton);                                                                                                                  →32
}

Each important line of code is explained as follows:

→2 The onCreateDialog() method is overridden and called when the showDialog() method is called with a parameter. The int id parameter is the ID that was passed into the showDialog() method previously.
→4 This line of code determines whether the ID passed into the onCreateDialog() is the same one that was passed in as a parameter to the showDialog() method. If it matches the DATE_PICKER_DIALOG value, it returns the value of the showDatePicker() method. The showDatePicker() call must return a Dialog type for onCreateDialog() to show a dialog box.
→10 The showDatePicker() method definition that returns a DatePickerDialog.
→13 On this line, you create a new DatePickerDialog that accepts the current context as the first parameter. You provide the current instance ReminderEditActivity.this as the Context. The full class name is included because it's inside a nested statement, therefore fully qualified names are required. The next parameter is the onDateSetListener(), which provides a callback that is defined from line 13 through line 22. This callback provides the value of the date that was chosen through the date picker. The other parameters for the DatePickerDialog are listed on line 25.
→17 The implementation of the onDateSet() method that is called when the user sets the date through the DatePickerDialog and clicks the Set button. This method provides the following parameters:
  • DatePicker view: The date picker used in the date selection dialog box
  • int year: The year that was set
  • int monthOfYear: The month that was set in format 0–11 for compatibility with the Calendar object
  • int dayOfMonth: The day of the month
→19 through →21 This code block uses a variable by the name of mCalendar. This is a classwide Calendar variable that allows me to keep track of the date and time that the user set while inside the ReminderEditActivity through the DatePickerDialog and TimePickerDialog. You also need this variable — define a classwide Calendar variable at the top of the class file with the name of mCalendar. In this code block, you use the setter and Calendar constants to change the date values of the Calendar object to that of the values the user set through the DatePickerDialog.
private Calendar mCalendar;
mCalendar = Calendar.getInstance();

Inside the onCreate() method, provide the mCalendar object with a value using the getInstance() method. This method returns a new instance of the Calendar object.

→22 After the mCalendar object has been updated, you make a call to updateDateButtonText() that updates the text of the button that the user clicked to open the DatePickerDialog. This method is explained on lines 29 through 31.
→25 These are the remaining parameters to set up the DatePickerDialog. These calendar values are what shows when DatePickerDialog opens. You use the mCalendar get accessor to retrieve the year, month, and day values of mCalendar. If mCalendar has not been previously set, these values are from today's date. If mCalendar has previously been set and the user decides to open the DatePickerDialog again to change the date, the mCalendar object returns the values that were set from the previous date selection as the default of the new DatePickerDialog.
→26 At the end of this method, you return an instance of the Dialog class because onCreateDialog() requires it. Because the DatePickerDialog class is a subclass of Dialog, you can return the DatePickerDialog. This allows onCreateDialog() to create the dialog box for the user to see onscreen.
→29 As shown on line 22, the updateDateButtonText() method is called after the mCalendar object is set up with new date values. This method is used to update the text of the Date button that the user selects when he wants to change the date. In this method, you set the button text to the value of the date that was selected so that the user can easily see what the reminder date is without having to open the DatePickerDialog.
→30 This line sets up a SimpleDateFormat object. This object is used to format and parse dates using a concrete class in a local-sensitive manner, such as either Gregorian or Hebrew calendars. Using the date formatting options listed in the Java documentation (http://download-llnw.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html), you can provide various output. On this line, I'm using a local constant called DATE_FORMAT as a parameter to set up the SimpleDateFormat. This constant defines the format in which you'd like the date information to be visible to the end user. You need to define this constant at the top of the class file as follows:
private static final String DATE_FORMAT = “yyyy-MM-dd”;

This date format is defined as “yyyy-MM-dd,” meaning a four-digit year, a two-digit month, and a two-digit day. Each is separated by a hyphen. An example of this would be 2010-09-10.

→31 On this line, I use the SimpleDateFormat object to format the mCalendar date by calling the getTime() method on the mCalendar object. This method returns a date object that the SimpleDateFormat object parses into the DATE_FORMAT that you specified on line 30. You then set the result — a string result — into a local variable.
→32 Using the local variable you set up on line 31, you set the text of the Date button using the Button class's setText() method.

The DatePickerDialog widget is now wired up to accept input from the user.

Wiring up the time picker

The TimePickerDialog allows users to select a time during the day in which they would like to be reminded of the task at hand.

Setting up a TimePickerDialog is almost identical to setting up a DatePickerDialog, the only thing that differs is that you'll be using a different constant and showing a different dialog. The first thing you need to do is declare the onClickListener() for the Time button. To do so, create a local mTimeButton variable at the top of the class file with the following code:

private Button mTimeButton;

You then need to initialize the variable in the onCreate() method as follows:

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

Setting up the Time button click listener

Now that you have a Time button to work with, you can set up the click listener for it. In the registerButtonListenersAndSetDefaultText() method, type the code shown in Listing 13-4.

Listing 13-4: Implementing the Time Button's OnClickListener

mTimeButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
       showDialog(TIME_PICKER_DIALOG);                               →4
    }
});

This entire method is the same as the Date button's onClickListener(), except that on line 4, you use a different constant as a parameter to the showDialog() method. You do this because when showDialog() is called, it in turn calls onCreateDialog() with that ID. When showDialog() calls onCreateDialog(), you can determine which dialog box to show according to the constant that you used in showDialog(). You need to create the TIME_PICKER_DIALOG constant at the top of the class file.

Now you need to go back to the onCreateDialog() method and add the following code after the return showDatePicker() code:

case TIME_PICKER_DIALOG:
    return showTimePicker();

Creating the showTimePicker() method

The showTimePicker() method has not been created. Create that method now by adding the full method definition in Listing 13-5.

Listing 13-5: The showTimePicker() Method

private TimePickerDialog showTimePicker() {
    TimePickerDialog timePicker = new TimePickerDialog(this, new
        TimePickerDialog.OnTimeSetListener() {                       →3
        @Override
        public void onTimeSet(TimePicker view, int hourOfDay, int minute){                                                →5
            mCalendar.set(Calendar.HOUR_OF_DAY, hourOfDay);          →6
            mCalendar.set(Calendar.MINUTE, minute);                  →7
            updateTimeButtonText();                                  →8
        }
    }, mCalendar.get(Calendar.HOUR_OF_DAY),                         →10
                  mCalendar.get(Calendar.MINUTE), true);            →11

    return timePicker;
}

The code in Listing 13-5 is fairly straightforward because it's almost identical to that of the showDatePicker() method. However, you can see differences on the following lines:

→3 Here a TimePickerDialog is being set up with a new OnTimeSetListener() that is called when the user sets the time with the TimePickerDialog.
→5 When the time is set, the hour and minute are passed into the onTimeSet() method, allowing you to perform necessary actions with the values.
→6 Here I am setting the classwide Calendar object's hour of the day.
→7 Here I am setting the classwide Calendar object's minute of the hour.
→8 This line delegates the updating of the Time button's text to a method called updateTimeButtonText(). This method is explained in Listing 13-6.
→10 This line specifies the default hour for the TimePickerDialog. This value is retrieved from the classwide Calendar object.
→11 This line specifies the default minute for the TimePickerDialog. This value is retrieved from the classwide Calendar object. The last parameter is set to the value of true, which informs the TimePickerDialog to show the time in 24-hour format as opposed to a 12-hour time format with a.m. and p.m. distinctions.

At the end of the method, the instance of the TimePickerDialog is returned to the onCreateDialog() method to allow it to show the dialog box to the end user.

On line 8, you made a call to updateTimeButtonText(). This method is very similar to the updateDateButtonText(), as shown previously in this chapter. Type the code from Listing 13-6 into the editor to create the updateTimeButtonText() method.

Listing 13-6: The updateTimeButtonText() Method

private void updateTimeButtonText() {
    SimpleDateFormat timeFormat = new SimpleDateFormat(TIME_FORMAT); →2
    String timeForButton = timeFormat.format(mCalendar.getTime());   →3
    mTimeButton.setText(timeForButton);                              →4
}

This code is explained as follows:

→2 This line of code creates a new SimpleDateFormat, but this time with a different constant. You need to create the TIME_FORMAT constant at the top of the class file as follows:
private static final String TIME_FORMAT = “kk:mm”;

This constant informs the SimpleDateFormat class that you would like the calendar to output the minutes and seconds separated by a colon. An example would be 12:45 to represent 12:45 p.m.

→3 This line formats the current calendar's time to that of the prescribed format on line 2.
→4 This line updates the button text to the time that was retrieved on line 3.

At this point, you've set up the date and time picker dialog widgets to accept values from the user. The best part is, you did not have to write the date and time logic; you simply had to respond to the click listeners.

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

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