1

How can I implement RecyclerView with the cursor. I tried to implement this code but this code uses some class to store each row but I did not want to make some class for the sake of storing each row of the cursor. And also I found this article which says that we don't need to make class when using the cursor. I am confused which approach to use and how to use it. I tried to implement most of the code present on stackOverFlow but they all are almost same.

And also i tried my code with this:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder>{
    private Cursor cursor;
    public class MyViewHolder extends RecyclerView.ViewHolder{
        TextView title,text;
        CardView cd;
        LinearLayout ll;
        public MyViewHolder(View v){
            super(v);
            title = v.findViewById(R.id.childTitleView);
            text = v.findViewById(R.id.childTextView);
            cd = v.findViewById(R.id.parentCardView);
            ll = v.findViewById(R.id.ll);
         }

    }

    public RecyclerViewAdapter(Cursor c){
        this.cursor = c;
    }

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

    @Override
    public void onBindViewHolder(final MyViewHolder holder, final int position) {
        cursor.moveToNext();
        String t = cursor.getString(cursor.getColumnIndex(RecordContract.RecordEntry.COLUMN_TITLE));
        String d = cursor.getString(cursor.getColumnIndex(RecordContract.RecordEntry.COLUMN_TEXT));
        holder.title.setText(t);
        holder.text.setText(d);
        holder.cd.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                Toast.makeText(view.getContext(), ""+position, Toast.LENGTH_SHORT).show();
                //holder.ll.setBackgroundColor(Color.parseColor("#000"));
                holder.cd.setBackgroundColor(Color.parseColor(view.getResources().getString(R.color.blueGreen)));
                return true;
            }
        });

    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_child,parent,false);
        return new MyViewHolder(itemView);
    }
}

This is My MainActivity

 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mdb = new RecordDbHelper(getApplicationContext());

        RecyclerView rv = findViewById(R.id.recylerViewId);
        rv.setLayoutManager(new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL));
        rv.setItemAnimator(new DefaultItemAnimator());
        Cursor c = getCursor();
        RecyclerViewAdapter rva = new RecyclerViewAdapter(c);
        rv.setAdapter(rva);
  }

   public Cursor getCursor(){
        SQLiteDatabase db = mdb.getReadableDatabase();
        String[] projection = {
            RecordContract.RecordEntry._ID,  RecordContract.RecordEntry.COLUMN_TEXT,
            RecordContract.RecordEntry.COLUMN_TITLE};
        String selection = null;
        String[] selectionArgs = null;
        String tableName = RecordContract.RecordEntry.TABLE_NAME;
        Cursor c = db.query(tableName,projection,selection,selectionArgs,null,null,null);
        return c;
    }

Well this show the text in the RecyclerView But when a new data is added to the database then the app requires to start again. It does not refresh itself.

Mayank Doda
  • 117
  • 2
  • 11

1 Answers1

3

Well this show the text in the RecyclerView

It will not do so reliably. In onBindViewHolder(), replace moveToNext() with moveToPosition(position). Right now, you are ignoring the position parameter, which means as soon as you start scrolling (particularly backwards), you will run into problems.

But when a new data is added to the database then the app requires to start again. It does not refresh itself.

That is no different than how CursorAdapter works with an AdapterView, such as a ListView.

When you update the database, you need to get a fresh Cursor and hand it to your RecyclerViewAdapter. Your RecyclerViewAdapter can then call notifyDataSetChanged() to tell the RecyclerView to redraw itself.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Is my method of accessing cursor in onBindViewHolder() correct? – Mayank Doda May 19 '18 at 14:23
  • @MayankDoda: As I mentioned, you need to replace `moveToNext()` with `moveToPosition(position)`. Otherwise, I do not see any problems with it. Personally, I would have most of that logic be in the `ViewHolder`, with `onBindViewHolder()` simply calling `moveToPosition()` and passing the `Cursor` to the `ViewHolder` to do the actual binding. – CommonsWare May 19 '18 at 14:39
  • can you help implementing the code for onResume function. i tried to use rva.notifydataSetChanged() in onResume but it doesnot work. – Mayank Doda May 19 '18 at 16:42
  • @MayankDoda: Sorry, but I do not know what you are doing in `onResume()` and I do not know what "doesnot work" means in this context. You might consider asking a separate Stack Overflow question, where you provide a fresh [mcve] and explain in detail the nature of your problem. – CommonsWare May 19 '18 at 16:45
  • for refreshing the recyclerView I was trying to use notifyDataSetChanged() method but RecyclerView doesn't update. It is showing the same data – Mayank Doda May 19 '18 at 16:54
  • @MayankDoda: Your `RecyclerView.Adapter` needs to be in position to work with the new data at that point. If your `RecyclerView.Adapter` still has your old `Cursor`, you will not see any changes. [This sample app](https://github.com/commonsguy/cw-omnibus/tree/v8.11/RecyclerView/VideoList) is the closest that I have to your scenario (though I'll have some closer ones coming out in a few weeks). In my case, I switch from a `null` `Cursor` to one delivered to me by the `CursorLoader`. I call `notifyDataSetChanged()` to get the `RecyclerView` to ask for new stuff from my adapter. – CommonsWare May 19 '18 at 17:01