public class AdapterWrapper implements ListAdapter {
ListAdapter delegate = null;
public AdapterWrapper(ListAdapter delegate) {
this.delegate = delegate;
}
public int getCount() {
return(delegate.getCount());
}
public Object getItem(int position) {
return(delegate.getItem(position));
}
public long getItemId(int position) {
return(delegate.getItemId(position));
}
public View getView(int position, View convertView,
ViewGroup parent) {
return(delegate.getView(position, convertView, parent));
}
public void registerDataSetObserver(DataSetObserver observer) {
delegate.registerDataSetObserver(observer);
}
public boolean hasStableIds() {
return(delegate.hasStableIds());
}
public boolean isEmpty() {
return(delegate.isEmpty());
}
public int getViewTypeCount() {
return(delegate.getViewTypeCount());
}
public int getItemViewType(int position) {
return(delegate.getItemViewType(position));
}
public void unregisterDataSetObserver(DataSetObserver observer) {
delegate.unregisterDataSetObserver(observer);
}
public boolean areAllItemsEnabled() {
return(delegate.areAllItemsEnabled());
}
public boolean isEnabled(int position) {
return(delegate.isEnabled(position));
}
}
We can then subclass AdapterWrapper to create RateableWrapper, overriding the default getView() but otherwise allowing the delegated ListAdapter to do the “real work:”
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; idelegate.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);
}
}
The idea is that RateableWrapper is where most of our rate-list logic resides. It puts the rating bars on the rows and it tracks the rating bars’ states as they are adjusted by the user. For the states, it has a float[] sized to fit the number of rows that the delegate says are in the list.