Search code examples
androidcursorandroid-cursoradapterandroid-recyclerview

Recyclerview adapter with CursorAdapter


I'm trying to implement an adapter for a Recyclerview with the use of CusrorAdapter as below as suggested in the one of the solutions here.

I am new to Android and I don't quite know how I should override CursorAdapter's newView method and bindView method. Also I am guessing that mine adapter will have multiple variables in ViewHolder instead of one (View v1) as there are several textViews in my layout file, but I just don't know how they all fit in in the code.

public class MyRecyclerAdapter extends Adapter<MyRecyclerAdapter.ViewHolder {

// PATCH: Because RecyclerView.Adapter in its current form doesn't natively support
// cursors, we "wrap" a CursorAdapter that will do all teh job for us
CursorAdapter mCursorAdapter;
Context mContext;

public MyRecyclerAdapter(Context context, Cursor c) {
    mContext = context;
    mCursorAdapter = new CursorAdapter(mContext, c, 0) {

        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            // Inflate the view here
        }

        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            // Binding operations

        }
    };
}

public static class ViewHolder extends RecyclerView.ViewHolder{
    View v1;
    public ViewHolder(View itemView) {
        super(itemView);
        v1 = itemView.findViewById(R.id.v1);
    }
}

@Override
public int getItemCount() {
    return mCursorAdapter.getCount();
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    // Passing the binding operation to cursor loader
    mCursorAdapter.bindView(holder.itemView, mContext, mCursorAdapter.getCursor());

}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    // Passing the inflater job to the cursor-adapter
    View v = mCursorAdapter.newView(mContext, mCursorAdapter.getCursor(), parent);
        return new ViewHolder(v);
    }
}

Solution

  • Somehow I managed to get it working although I don't understand how it works in details. Basically I added a ViewHolder variable as a class variable and change some parts of the code. The solution looks something like this when you have 2 TextView items (name and date) in your layout file called row.xml:

    public class MyRecyclerAdapter extends Adapter<MyRecyclerAdapter.ViewHolder>{
    
        // PATCH: Because RecyclerView.Adapter in its current form doesn't natively support
        // cursors, we "wrap" a CursorAdapter that will do all teh job for us
        private CursorAdapter mCursorAdapter;
        private Context mContext;
        private ViewHolder holder;
    
        public MyRecyclerAdapter(Context context, Cursor c) {
            mContext = context;
            mCursorAdapter = new CursorAdapter(mContext, c, 0) {
    
                @Override
                public View newView(Context context, Cursor cursor, ViewGroup parent) {
                    // Inflate the view here
                    View v = LayoutInflater.from(context)
                        .inflate(R.layout.row_rv, parent, false);
                    return v;
                }
    
                @Override
                public void bindView(View view, Context context, Cursor cursor) {
                    // Binding operations
                    String name = cursor.getString(cursor.getColumnIndexOrThrow("name"));
                    String date = cursor.getString(cursor.getColumnIndexOrThrow("date"));
    
                    holder.tvName.setText(name);
                    holder.tvDate.setText(date);
                }
            };
        }
    
        public static class ViewHolder extends RecyclerView.ViewHolder{
            public TextView tvName;
            public TextView tvDate;
    
            public ViewHolder(View itemView) {
                super(itemView);
                tvName = (TextView) itemView.findViewById(R.id.name);
                tvDate = (TextView) itemView.findViewById(R.id.date);
            }
        }
    
        @Override
        public int getItemCount() {
            return mCursorAdapter.getCount();
        }
    
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            // Passing the binding operation to cursor loader
            mcursorAdapter.getCursor().moveToPosition(position);
            mCursorAdapter.bindView(holder.itemView, mContext, mCursorAdapter.getCursor());
        }
    
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            // Passing the inflater job to the cursor-adapter
            View v = mCursorAdapter.newView(mContext, mCursorAdapter.getCursor(), parent);
            holder = new ViewHolder(v);
            return holder;
        }
    }
    

    If anyone knows why it works, please feel free to join in the discussion. Thanks.