}
void setRatingBar(RatingBar rate) {
this.rate = rate;
}
View getGuts() {
if (guts==null) {
guts = base.getChildAt(1);
}
return(guts);
}
void setGuts(View guts) {
this.guts = guts;
}
}
With all that in place, RateListView
is comparatively simple:
public class RateListView extends ListView {
public RateListView(Context context) {
super(context);
}
public RateListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RateListView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
public void setAdapter(ListAdapter adapter) {
super.setAdapter(new RateableWrapper(getContext(), adapter));
}
}
We simply subclass ListView
and override setAdapter()
so we can wrap the supplied ListAdapter
in our own RateableWrapper
.
Visually, the results are similar to the RateListDemo
, albeit without top-rated words appearing in all caps (see Figure 9-5).

Figure 9-5.
The difference is in reusability. We could package RateListView
in its own JAR and plop it into any Android project where we need it. So while RateListView
is somewhat complicated to write, we have to write it only once, and the rest of the application code is blissfully simple.
Of course, this RateListView
could use some more features, such as programmatically changing states (updating both the float[]
and the actual RatingBar
itself), allowing other application logic to be invoked when a RatingBar
state is toggled (via some sort of callback), etc.
CHAPTER 10
Employing Fancy Widgets and Containers
The widgets and containers covered to date are not only found in many GUI toolkits (in one form or fashion), but also are widely used in building GUI applications, whether Web-based, desktop, or mobile. The widgets and containers in this chapter are a little less widely used, though you will likely find many to be quite useful.
Pick and Choose
With limited-input devices like phones, having widgets and dialogs that are aware of the type of stuff somebody is supposed to be entering is very helpful. It minimizes keystrokes and screen taps, plus reduces the chance of making some sort of error (e.g., entering a letter someplace where only numbers are expected).
As previously shown, EditText
has content-aware flavors for entering in numbers, phone numbers, etc. Android also supports widgets (DatePicker
, TimePicker
) and dialogs (DatePickerDialog
, TimePickerDialog
) for helping users enter dates and times.
The DatePicker
and DatePickerDialog
allow you to set the starting date for the selection, in the form of a year, month, and day of month value. Note that the month runs from 0 for January through 11 for December. Most importantly, each let you provide a callback object (OnDateChangedListener
or OnDateSetListener
) where you are informed of a new date selected by the user. It is up to you to store that date someplace, particularly if you are using the dialog, since there is no other way for you to get at the chosen date later on.
Similarly, TimePicker
and TimePickerDialog
let you:
• set the initial time the user can adjust, in the form of an hour (0 through 23) and a minute (0 through 59)
• indicate if the selection should be in 12-hour mode with an AM/PM toggle, or in 24-hour mode (what in the US is thought of as “military time” and in the rest of the world is thought of as “the way times are supposed to be”)
• provide a callback object (OnTimeChangedListener
or OnTimeSetListener
) to be notified of when the user has chosen a new time, which is supplied to you in the form of an hour and minute
The Fancy/Chrono
sample project, found along with all other code samples in this chapter in the Source Code area of http://apress.com, shows a trivial layout containing a label and two buttons — the buttons will pop up the dialog flavors of the date and time pickers:
<?xml version='1.0' encoding='utf-8'?>
<LinearLayout
xmlns:android='http://schemas.android.com/apk/res/android'
android:orientation='vertical'
android:layout_width='fill_parent'