15

When overriding ArrayAdapter I know is correct using a pattern like this:

if(view != null){
   ...create new view setting fields from data 
}else
  return view; //reuse view

is correct too using this pattern with CursorAdapters? My problem is that I have a textcolor which can be red or blue according to a cursor field, so I don't want any errors like a red color on a cell which has a field needing blue color. My bindView code is something like this:

if(c.getString(2).equals("red"))
      textView.setTextColor(<red here>);
   else
      textView.setTextColor(<blue here>);

if I reuse view can I be sure that red goes on red, while blue goes on blue?

user1610075
  • 1,483
  • 3
  • 15
  • 31

2 Answers2

37

In CursorAdapter, you get layout in newView and bind data in bindView. CursorAdapter already do reuse pattern in getView so you don't have to do it again. Below is the original getView source code.

  public View getView(int position, View convertView, ViewGroup parent) {
    if (!mDataValid) {
        throw new IllegalStateException("this should only be called when the cursor is valid");
    }
    if (!mCursor.moveToPosition(position)) {
        throw new IllegalStateException("couldn't move cursor to position " + position);
    }
    View v;
    if (convertView == null) {
        v = newView(mContext, mCursor, parent);
    } else {
        v = convertView;
    }
    bindView(v, mContext, mCursor);
    return v;
}

If you want further optimization using ViewHolder Pattern here is example: Create tag in newView and retrieve in bindView

    public class TimeListAdapter extends CursorAdapter {
     private LayoutInflater inflater;
     private    static  class   ViewHolder  {
         int    nameIndex;
         int    timeIndex;
         TextView   name;
         TextView   time;
    }
  public TimeListAdapter(Context context, Cursor c, int flags) {
    super(context, c, flags);
  this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  }
  @Override
  public void bindView(View view, Context context, Cursor cursor) {
         ViewHolder holder  =   (ViewHolder)    view.getTag();
         holder.name.setText(cursor.getString(holder.nameIndex));
         holder.time.setText(cursor.getString(holder.timeIndex));
  }
  @Override
  public View newView(Context context, Cursor cursor, ViewGroup  
  p parent) {
         View   view    =   inflater.inflate(R.layout.time_row, null);
         ViewHolder holder  =   new ViewHolder();
         holder.name    =   (TextView)  view.findViewById(R.id.task_name);
         holder.time    =   (TextView)  view.findViewById(R.id.task_time);
     holder.nameIndex   =   cursor.getColumnIndexOrThrow 
         (TaskProvider.Task.NAME);
         holder.timeIndex   =   cursor.getColumnIndexOrThrow    
         (TaskProvider.Task.DATE);
         view.setTag(holder);
    return view;
  }
}
DustNSummers
  • 163
  • 1
  • 10
Trung Nguyen
  • 7,192
  • 2
  • 40
  • 82
  • 8
    I would probably add `LayoutInflater.from(context)` as a global variable set in constructor, so it won't need to be got each time `newView` is run. – HGPB Jan 26 '13 at 17:07
  • Is the ViewHolder still valid today? or is there a new simpler/different way? – Yosi199 Apr 11 '13 at 12:57
  • You can replace the ViewHolder pattern using `view.setTag(int key,Object obj)` and `view.getTag(int key)` – vamsiampolu Oct 28 '13 at 04:29
2

Yes, getView is in Adapter and is not dependant from ArrayAdapter nor CursorAdapter.

recycling is always a good practice. Ensure that your code sets a colour in every situation.

rds
  • 24,304
  • 16
  • 97
  • 124
  • start with `textView.setTextColor()` and then process colors like you do – rds Aug 31 '12 at 23:01
  • Something like: if(view != null) view.setTextcolor(); else { ?} – user1610075 Aug 31 '12 at 23:18
  • my pattern is rather `if (view==null) {view=layoutinflater.inflate(...)} view.setText(...);` – rds Aug 31 '12 at 23:36
  • Or if your adapter inherits from `SimpleCursorAdapter` simply do `view=super.getView(); view.setText(...)` That way, it will be recycled and non-null – rds Aug 31 '12 at 23:37