androidandroid-recyclerviewandroid-cursorsectionedrecyclerviewadapter

Implementation of RecyclerView with cursor Adapter


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.


Solution

  • 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.