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】:
是的,getView
在 Adapter
中,不依赖于 ArrayAdapter
也不依赖于 CursorAdapter
。
回收总是一种很好的做法。确保您的代码在每种情况下都设置了颜色。
【讨论】:
从textView.setTextColor(<default>)
开始,然后像你一样处理颜色
类似:if(view != null) view.setTextcolor(); else ?
我的模式是if (view==null) view=layoutinflater.inflate(...) view.setText(...);
或者如果你的adapter继承自SimpleCursorAdapter
干脆做view=super.getView(); view.setText(...)
那样,它会被回收并且非空以上是关于CursorAdapter bindView 优化的主要内容,如果未能解决你的问题,请参考以下文章