CursorAdapter bindView 优化

Posted

技术标签:

【中文标题】CursorAdapter bindView 优化【英文标题】:CursorAdapter bindView optimization 【发布时间】:2012-08-26 17:46:42 【问题描述】:

当我知道使用这样的模式覆盖 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>);

如果我重用视图,我可以确定红色变红色,而蓝色变蓝色吗?

【问题讨论】:

【参考方案1】:

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;
  

【讨论】:

我可能会在构造函数中添加LayoutInflater.from(context)作为全局变量集,因此每次运行newView时都不需要获取它。 ViewHolder 今天还有效吗?还是有新的更简单/不同的方式? 您可以使用 view.setTag(int key,Object obj)view.getTag(int key) 替换 ViewHolder 模式【参考方案2】:

是的,getViewAdapter 中,不依赖于 ArrayAdapter 也不依赖于 CursorAdapter

回收总是一种很好的做法。确保您的代码在每种情况下都设置了颜色。

【讨论】:

textView.setTextColor(&lt;default&gt;)开始,然后像你一样处理颜色 类似:if(view != null) view.setTextcolor(); else ? 我的模式是if (view==null) view=layoutinflater.inflate(...) view.setText(...); 或者如果你的adapter继承自SimpleCursorAdapter干脆做view=super.getView(); view.setText(...)那样,它会被回收并且非空

以上是关于CursorAdapter bindView 优化的主要内容,如果未能解决你的问题,请参考以下文章

Bindview 在 Eclipse 中不起作用

ButterKnife与BindView使用详解

Android CursorAdapter的使用

SimpleCursorAdapter 在 bindView 上重复单击操作

手动实现bindview

VFP CursorAdapter 起步二(作者:Dung Hennig 译者:fbilo)