Оптимизация CursorAdapter bindView

Я знаю, что при переопределении ArrayAdapter правильно использовать такой шаблон:

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

также правильно использовать этот шаблон с CursorAdapters? Моя проблема в том, что у меня есть цвет текста, который может быть красным или синим в зависимости от поля курсора, поэтому я не хочу никаких ошибок, таких как красный цвет в ячейке, в которой есть поле, требующее синего цвета. Мой код bindView выглядит примерно так:

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

если я повторно использую представление, могу ли я быть уверен, что красный будет красным, а синий - синим?


person user1610075    schedule 31.08.2012    source источник


Ответы (2)


В CursorAdapter вы получаете макет в newView и привязываете данные в bindView. CursorAdapter уже использует шаблон повторного использования в getView, поэтому вам не нужно делать это снова. Ниже приведен оригинальный исходный код getView.

  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;
}

Если вам нужна дальнейшая оптимизация с использованием ViewHolder Pattern, вот пример: Создайте тег в newView и получите в 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;
  }
}
person Trung Nguyen    schedule 01.09.2012
comment
Я бы, вероятно, добавил LayoutInflater.from(context) в качестве глобальной переменной, установленной в конструкторе, поэтому ее не нужно будет получать каждый раз при запуске newView. - person HGPB; 26.01.2013
comment
Является ли ViewHolder действительным сегодня? или есть новый более простой/другой способ? - person Yosi199; 11.04.2013
comment
Вы можете заменить шаблон ViewHolder, используя view.setTag(int key,Object obj) и view.getTag(int key) - person vamsiampolu; 28.10.2013

Да, getView находится в Adapter и не зависит ни от ArrayAdapter, ни от CursorAdapter.

переработка всегда является хорошей практикой. Убедитесь, что ваш код устанавливает цвет в каждой ситуации.

person rds    schedule 31.08.2012
comment
начните с textView.setTextColor(<default>), а затем обработайте цвета, как вы - person rds; 01.09.2012
comment
Что-то вроде: if(view != null) view.setTextcolor(); else { ‹создать весь вид› ?} - person user1610075; 01.09.2012
comment
моя модель скорее if (view==null) {view=layoutinflater.inflate(...)} view.setText(...); - person rds; 01.09.2012
comment
Или, если ваш адаптер наследуется от SimpleCursorAdapter, просто выполните view=super.getView(); view.setText(...) Таким образом, он будет переработан и не будет нулевым. - person rds; 01.09.2012