ViewHolder 模式在自定义 CursorAdapter 中正确实现?
这是我的自定义 CursorAdapter:
public class TasksAdapter extends CursorAdapter implements Filterable {
private final Context context;
public TasksAdapter(Context context, Cursor c) {
super(context, c);
this.context = context;
}
/**
* @see android.widget.CursorAdapter#newView(android.content.Context, android.database.Cursor, android.view.ViewGroup)
*/
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(android.R.layout.simple_list_item_checked, parent, false);
ViewHolder holder = new ViewHolder();
holder.textview = (CheckedTextView)v.findViewById(android.R.id.text1);
v.setTag(holder);
return v;
}
/**
* @see android.widget.CursorAdapter#bindView(android.view.View, android.content.Context, android.database.Cursor)
*/
@Override
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder holder = (ViewHolder)view.getTag();
int titleCol = cursor.getColumnIndexOrThrow(Tasks.TITLE);
int completedCol = cursor.getColumnIndexOrThrow(Tasks.COMPLETED);
String title = cursor.getString(titleCol);
boolean completed = Util.intToBool(cursor.getInt(completedCol));
holder.textview.setText(title);
holder.textview.setChecked(completed);
}
/**
* @see android.widget.CursorAdapter#runQueryOnBackgroundThread(java.lang.CharSequence)
*/
@Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
StringBuffer buffer = null;
String[] args = null;
if (constraint != null) {
buffer = new StringBuffer();
buffer.append("UPPER (");
buffer.append(Tasks.TITLE);
buffer.append(") GLOB ?");
args = new String[] { "*" + constraint.toString().toUpperCase() + "*" };
}
Cursor c = context.getContentResolver().query(Tasks.CONTENT_URI,
null, (buffer == null ? null : buffer.toString()), args,
Tasks.DEFAULT_SORT_ORDER);
c.moveToFirst();
return c;
}
/**
* @see android.widget.CursorAdapter#convertToString(android.database.Cursor)
*/
@Override
public CharSequence convertToString(Cursor cursor) {
final int titleCol = cursor.getColumnIndexOrThrow(Tasks.TITLE);
String title = cursor.getString(titleCol);
return title;
}
static class ViewHolder {
CheckedTextView textview;
}
}
这是否属于 ViewHolder 模式的约束?我不确定,因为这是一个 CursorAdapter,其中没有 getView
。如果有什么问题或建议,请指出。
Here is my custom CursorAdapter:
public class TasksAdapter extends CursorAdapter implements Filterable {
private final Context context;
public TasksAdapter(Context context, Cursor c) {
super(context, c);
this.context = context;
}
/**
* @see android.widget.CursorAdapter#newView(android.content.Context, android.database.Cursor, android.view.ViewGroup)
*/
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(android.R.layout.simple_list_item_checked, parent, false);
ViewHolder holder = new ViewHolder();
holder.textview = (CheckedTextView)v.findViewById(android.R.id.text1);
v.setTag(holder);
return v;
}
/**
* @see android.widget.CursorAdapter#bindView(android.view.View, android.content.Context, android.database.Cursor)
*/
@Override
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder holder = (ViewHolder)view.getTag();
int titleCol = cursor.getColumnIndexOrThrow(Tasks.TITLE);
int completedCol = cursor.getColumnIndexOrThrow(Tasks.COMPLETED);
String title = cursor.getString(titleCol);
boolean completed = Util.intToBool(cursor.getInt(completedCol));
holder.textview.setText(title);
holder.textview.setChecked(completed);
}
/**
* @see android.widget.CursorAdapter#runQueryOnBackgroundThread(java.lang.CharSequence)
*/
@Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
StringBuffer buffer = null;
String[] args = null;
if (constraint != null) {
buffer = new StringBuffer();
buffer.append("UPPER (");
buffer.append(Tasks.TITLE);
buffer.append(") GLOB ?");
args = new String[] { "*" + constraint.toString().toUpperCase() + "*" };
}
Cursor c = context.getContentResolver().query(Tasks.CONTENT_URI,
null, (buffer == null ? null : buffer.toString()), args,
Tasks.DEFAULT_SORT_ORDER);
c.moveToFirst();
return c;
}
/**
* @see android.widget.CursorAdapter#convertToString(android.database.Cursor)
*/
@Override
public CharSequence convertToString(Cursor cursor) {
final int titleCol = cursor.getColumnIndexOrThrow(Tasks.TITLE);
String title = cursor.getString(titleCol);
return title;
}
static class ViewHolder {
CheckedTextView textview;
}
}
Does this fall into the constraints of the ViewHolder pattern? I wasn't sure because this was a CursorAdapter, where there was no getView
. If there are any problems or suggestions, could you please point them out.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
CursorAdapter
不会在每次需要新行时调用newView
;如果它已经有一个View
,它将调用bindView
,因此创建的视图实际上被重用。也就是说,正如 Joseph 在评论中指出的,您仍然可以使用 ViewHolder 以避免重复调用
findViewById
。如果您仍然担心效率,请查看
SimpleCursorAdapter
实现,它使用 < code>WeakHashMap(WeakReferences
的映射):CursorAdapter
won't call thenewView
each time it needs a new row; if it already has aView
, it will call thebindView
, so the created view is actually reused.That said, as pointed out by Joseph in the comments, you can still use ViewHolder in order to avoid calling
findViewById
repeatedly.If you are still concerned about efficiency then take a look at the
SimpleCursorAdapter
implementation, which uses aWeakHashMap
(a map ofWeakReferences
):如果您要重写
newView()
和bindView()
,则无需在getView()
中执行任何额外操作。 CursorAdapter 具有getView()
的实现,该实现委托给newView()
和bindView()
来强制执行行回收。findViewById()
在ListView
滚动期间可能会被频繁调用,这会降低性能。即使适配器返回一个膨胀的视图进行回收,您仍然需要查找元素并更新它们。为了避免这种情况,ViewHolder
模式很有用。以下是为天气应用程序实现的
ViewHolder
模式示例:If you are overriding
newView()
andbindView()
, you don't need to do anything extra ingetView()
.CursorAdapter
has an implementation ofgetView()
that delegates tonewView()
andbindView()
to enforce the row recycling.findViewById()
maybe called frequently during the scrolling ofListView
, which can slow down performance. Even when theAdapter
returns an inflated view for recycling, you still need to look up the elements and update them. To avoid this,ViewHolder
pattern is useful.Here's an example of
ViewHolder
pattern implemented for a weather app:我的类实现使用
newView
和bindView
扩展 SimpleCursorAdapter,但没有ViewHolder
模式My implementation of a class extends SimpleCursorAdapter with
newView
andbindView
but without theViewHolder
pattern