android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Set the Date"
/>
<Button android:id="@+id/timeBtn"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Set the Time"
/>
</LinearLayout>
The more interesting stuff comes in the Java source:
public class ChronoDemo extends Activity {
DateFormat fmtDateAndTime = DateFormat.getDateTimeInstance();
TextView dateAndTimeLabel;
Calendar dateAndTime = Calendar.getInstance();
DatePickerDialog.OnDateSetListener d =
new DatePickerDialog.OnDateSetListener() {
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
dateAndTime.set(Calendar.YEAR, year);
dateAndTime.set(Calendar.MONTH, monthOfYear);
dateAndTime.set(Calendar.DAY_OF_MONTH, dayOfMonth);
updateLabel();
}
};
TimePickerDialog.OnTimeSetListener t =
new TimePickerDialog.OnTimeSetListener() {
public void onTimeSet(TimePicker view, int hourOfDay,
int minute) {
dateAndTime.set(Calendar.HOUR_OF_DAY, hourOfDay);
dateAndTime.set(Calendar.MINUTE, minute);
updateLabel();
}
};
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
Button btn = (Button)findViewById(R.id.dateBtn);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
new DatePickerDialog(ChronoDemo.this, d,
dateAndTime.get(Calendar.YEAR), dateAndTime.get(Calendar.MONTH),
dateAndTime.get(Calendar.DAY_OF_MONTH)).show();
}
});
btn = (Button)findViewById(R.id.timeBtn);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
new TimePickerDialog(ChronoDemo.this, t,
dateAndTime.get(Calendar.HOUR_OF_DAY), dateAndTime.get(Calendar.MINUTE),
true).show();
}
});
dateAndTimeLabel = (TextView)findViewById(R.id.dateAndTime);
updateLabel();
}
private void updateLabel() {
dateAndTimeLabel.setText(fmtDateAndTime.format(dateAndTime.getTime()));
}
}
The “model” for this activity is just a Calendar instance, initially set to be the current date and time. We pour it into the view via a DateFormat formatter. In the updateLabel() method, we take the current Calendar, format it, and put it in the TextView.
Each button is given a OnClickListener callback object. When the button is clicked, either a DatePickerDialog or a TimePickerDialog is shown. In the case of the DatePickerDialog, we give it a OnDateSetListener callback that updates the Calendar with the new date (year, month, day of month). We also give the dialog the last-selected date, getting the values out of the Calendar. In the case of the TimePickerDialog, it gets a OnTimeSetListener callback to update the time portion of the Calendar, the last-selected time, and a true indicating we want 24-hour mode on the time selector.
With all this wired together, the resulting activity is shown in Figures 10-1, 10-2, and 10-3.
Figure 10-1. The ChronoDemo sample application, as initially launched
Figure 10-2. The same application, showing the date picker dialog
Figure 10-3. The same application, showing the time picker dialog
Time Keeps Flowing Like a River
If you want to display the time, rather than have users enter the time, you may wish to use the DigitalClock or AnalogClock widgets. These are extremely easy to use, as they automatically update with the passage of time. All you need to do is put them in your layout and let them do their thing.
For example, from the Fancy/Clocks sample application, here is an XML layout containing both DigitalClock and AnalogClock:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<AnalogClock android:id="@+id/analog"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true"
/>
<DigitalClock android:id="@+id/digital"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="@id/analog"
/>
</RelativeLayout>
Without any Java code other than the generated stub, we can build this project (see Figure 10-4).