Выбрать главу

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.