关于使用CursorAdapter的RecyclerView的疑虑

8 浏览
0 Comments

关于使用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 CursorRecyclerViewAdapter extends 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()方法
        }
    }
}

0
0 Comments

在使用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)。

0
0 Comments

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();

}

}

0