|
You may remember way back when (e.g., July 2008) when
Building ‘Droids
featured a six-post series on creating fancy ListView implementations, culminating
in a CheckListView
widget that could be used as a drop-in replacement for ListView.
They’re ba-ack!
Specifically, today, let’s take a look at the 0.9 SDK’s impact
on the Fancy ListView series, and update one of the examples to take advantage of
a new widget: the RatingBar.
In many respects, the code and techniques introduced in the Fancy
ListViews series are still valid and relevant in the world of the 0.9 SDK. Perhaps
the biggest change is that ViewInflate became LayoutInflater,
requiring some search-and-replace edits of your older M5 source code. But the concepts
of supplying custom views, of recycling views using the ViewHolder/ViewWrapper
pattern, and the like are still very useful, even after the 0.9 SDK.
Of course, as promised, the 0.9 SDK has its own take on having
checkable ListView widgets; this will be covered in a future blog post.
For now, though, let’s revisit the
last sample
from the Fancy ListViews series and update it to eschew the checkbox, switching
to the new RatingBar.
RatingBar is a widget designed to users to provide
a rating to something, such as rating a music track or a blog post or an Android
development book up on Amazon.com (*cough*). A rating is a float, from
0 to a specified maximum (android:numStars). You can specify
what the granularity of the rating is (android:stepSize) and whether
it is merely an indicator (android:isIndicator) or if it is a user-input
element to allow users to set the rating by sliding their finger across the stars.
As with just about any moderately-sized widget, the RatingBar
can be used as part of a row in a ListView. In fact, replacing the
CheckBox in CheckListView with a RatingBar
is fairly straight-forward:
- public
class RateableWrapper
extends AdapterWrapper {
- Context ctxt=null;
- float[] rates=null;
-
- public RateableWrapper(Context
ctxt, ListAdapter delegate) {
- super(delegate);
-
- this.ctxt=ctxt;
- this.rates=new
float[delegate.getCount()];
-
- for (int
i=0;i<delegate.getCount();i++) {
- this.rates[i]=2.0f;
- }
- }
-
- public View getView(int
position, View convertView, ViewGroup parent) {
- ViewWrapper wrap=null;
- View row=convertView;
-
- if (convertView==null)
{
- LinearLayout layout=new LinearLayout(ctxt);
- RatingBar rate=new RatingBar(ctxt);
-
- rate.setNumStars(3);
- rate.setStepSize(1.0f);
-
- View guts=delegate.getView(position,
null, parent);
-
- layout.setOrientation(LinearLayout.HORIZONTAL);
-
- rate.setLayoutParams(new LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.WRAP_CONTENT,
- LinearLayout.LayoutParams.FILL_PARENT));
- guts.setLayoutParams(new LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.FILL_PARENT,
- LinearLayout.LayoutParams.FILL_PARENT));
-
- RatingBar.OnRatingBarChangeListener l=new
RatingBar.OnRatingBarChangeListener() {
- public
void onRatingChanged(RatingBar ratingBar,
float rating, boolean
fromTouch) {
- rates[(Integer)ratingBar.getTag()]=rating;
- }
- };
-
- rate.setOnRatingBarChangeListener(l);
-
- layout.addView(rate);
- layout.addView(guts);
-
- wrap=new ViewWrapper(layout);
- wrap.setGuts(guts);
- layout.setTag(wrap);
-
- rate.setTag(new Integer(position));
- rate.setRating(rates[position]);
-
- row=layout;
- }
- else {
- wrap=(ViewWrapper)convertView.getTag();
- wrap.setGuts(delegate.getView(position, wrap.getGuts(), parent));
- wrap.getRatingBar().setTag(new
Integer(position));
- wrap.getRatingBar().setRating(rates[position]);
- }
-
- return(row);
- }
- }
- Create and configure the
RatingBar when it is lazy-instantiated
in getView()
- Hook in a
RatingBar.OnRatingBarChangeListener to update a
float[] of ratings, rather than a boolean[] of checkbox
states
- Update the rating in the
RatingBar when it is recycled
- Rename all the classes to something more logical (e.g.,
CheckableWrapper
becomes RateableWrapper)
Unfortunately, the stock style for RatingBar is
a bit big for lists:

You can use a ratingBarStyleSmall style to shrink
the size, but then the RatingBar becomes read-only, meaning you would
need some other means to let people specify the rating itself.
Source: http://androidguys.com/2008/08/26/fancy-listviews-redux-09-sdk-and-ratingbar/
 |
ugg boots for sale