关于使用CursorAdapter的RecyclerView的疑虑
关于使用CursorAdapter的RecyclerView的疑虑
我阅读了有关RecyclerView和Cursor适配器的这个线程,并尝试使用第一个解决方案。我对OnViewHolder函数的实现感到困惑。我知道OnViewHolder可以通过(ViewHolder, int)或(ViewHolder, Cursor)来调用,但我不知道如何在我的项目中使用它。\n这是我的原始适配器:\n
public class FeedAdapter extends CursorAdapter { // 调试标签 private static final String TAG = FeedAdapter.class.getSimpleName(); // 用于避免多次调用findViewById()的视图持有者 static class ViewHolder { TextView titulo; TextView descripcion; int tituloI; int descripcionI; } public FeedAdapter(Context context, Cursor c, int flags) { super(context, c, flags); } public View newView(Context context, Cursor cursor, ViewGroup parent) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); View view = inflater.inflate(R.layout.item_layout, null, false); ViewHolder vh = new ViewHolder(); // 存储引用 vh.titulo = (TextView) view.findViewById(R.id.titulo); vh.descripcion = (TextView) view.findViewById(R.id.descripcion); // 设置索引 vh.tituloI = cursor.getColumnIndex(ScriptDatabase.ColumnEntradas.TITULO); vh.descripcionI = cursor.getColumnIndex(ScriptDatabase.ColumnEntradas.DESCRIPCION); view.setTag(vh); return view; } public void bindView(View view, Context context, Cursor cursor) { final ViewHolder vh = (ViewHolder) view.getTag(); // 设置标题文本 vh.titulo.setText(cursor.getString(vh.tituloI)); // 获取描述和其长度 vh.descripcion.setText(descripcion); } }
\n我使用RecyclerView的新适配器。OnBindViewHolder未完成,因为我不知道如何设置它:\n
public class RVAdapter extends CursorRecyclerViewAdapter{ private Cursor mCursorAdapter; public RVAdapter(Context context, Cursor cursor){ super(context,cursor); } public static class ViewHolder extends RecyclerView.ViewHolder { CardView cv; TextView titulo; TextView descripcion; int tituloI; int descripcionI; public ViewHolder (View view){ super(view); cv = (CardView) itemView.findViewById(R.id.cv); titulo = (TextView) itemView.findViewById(R.id.titulo); descripcion = (TextView) itemView.findViewById(R.id.descripcion); } } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_layout, parent, false); ViewHolder vh = new ViewHolder(itemView); return vh; } @Override public void onBindViewHolder(ViewHolder viewHolder, int position) { mCursorAdapter.moveToPosition(position); final ViewHolder vh = (ViewHolder) view.getTag(); } }
\n在这种情况下,我应该使用\"onBindViewHolder(ViewHolder viewHolder, Cursor cursor)\"吗?我该如何使其工作?\nEDIT 1\n这是扩展了我的RVAdapter的抽象类:\n
public abstract class CursorRecyclerViewAdapterextends RecyclerView.Adapter { private Context mContext; private Cursor mCursor; private boolean mDataValid; private int mRowIdColumn; private DataSetObserver mDataSetObserver; public CursorRecyclerViewAdapter(Context context, Cursor cursor) { mContext = context; mCursor = cursor; mDataValid = cursor != null; mRowIdColumn = mDataValid ? mCursor.getColumnIndex("_id") : -1; mDataSetObserver = new NotifyingDataSetObserver(); if (mCursor != null) { mCursor.registerDataSetObserver(mDataSetObserver); } } public Cursor getCursor() { return mCursor; } @Override public int getItemCount() { if (mDataValid && mCursor != null) { return mCursor.getCount(); } return 0; } @Override public long getItemId(int position) { if (mDataValid && mCursor != null && mCursor.moveToPosition(position)) { return mCursor.getLong(mRowIdColumn); } return 0; } @Override public void setHasStableIds(boolean hasStableIds) { super.setHasStableIds(true); } public abstract void onBindViewHolder(VH viewHolder, Cursor cursor); @Override public void onBindViewHolder(VH viewHolder, int position) { 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); } onBindViewHolder(viewHolder, mCursor); } /** * 更改底层游标为新游标。如果存在旧游标,将关闭它。 */ public void changeCursor(Cursor cursor) { Cursor old = swapCursor(cursor); if (old != null) { old.close(); } } /** * 交换新游标,返回旧游标。与changeCursor(Cursor)不同,返回的旧游标不会被关闭。 */ public Cursor swapCursor(Cursor newCursor) { if (newCursor == mCursor) { return null; } final Cursor oldCursor = mCursor; if (oldCursor != null && mDataSetObserver != null) { oldCursor.unregisterDataSetObserver(mDataSetObserver); } mCursor = newCursor; if (mCursor != null) { if (mDataSetObserver != null) { mCursor.registerDataSetObserver(mDataSetObserver); } mRowIdColumn = newCursor.getColumnIndexOrThrow("_id"); mDataValid = true; notifyDataSetChanged(); } else { mRowIdColumn = -1; mDataValid = false; notifyDataSetChanged(); // RecyclerView.Adapter没有notifyDataSetInvalidated()方法 } return oldCursor; } private class NotifyingDataSetObserver extends DataSetObserver { @Override public void onChanged() { super.onChanged(); mDataValid = true; notifyDataSetChanged(); } @Override public void onInvalidated() { super.onInvalidated(); mDataValid = false; notifyDataSetChanged(); // RecyclerView.Adapter没有notifyDataSetInvalidated()方法 } } }
在使用RecyclerView和CursorAdapter时,遇到了一些疑问。首先,使用Cursor是因为它更节省内存。然后,问题出现在onBindViewHolder方法中,如果使用Cursor,position参数不能是int类型,而是Cursor类型,并且需要使用moveToPosition方法来移动位置。那么如何使用Cursor类型来移动位置呢?解决方法是将onBindViewHolder方法的参数改为public void onBindViewHolder(ViewHolder viewHolder, Cursor cursor)。这样就可以使用Cursor类型来移动位置了。另外,需要注意的是,在RVAdapter.onBindViewHolder方法中,方法签名必须是public void onBindViewHolder(ViewHolder, int)。
public void onBindViewHolder(ViewHolder viewHolder, Cursor cursor) {
cursor.moveToPosition(viewHolder.getAdapterPosition());
String title = cursor.getString(cursor.getColumnIndex("title"));
viewHolder.txttitle.setText(title);
viewHolder.rootItem.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
}
});
}
public abstract void onBindViewHolder(ViewHolder viewHolder, Cursor cursor);
public class CursorRecyclerViewAdapter extends RecyclerView.Adapter
private Cursor mCursor;
public CursorRecyclerViewAdapter(Cursor cursor) {
mCursor = cursor;
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
onBindViewHolder(viewHolder, mCursor);
}
@Override
public int getItemCount() {
return mCursor.getCount();
}
}