0

I have an activity called ListActivity containing of a recycler view and a Loader, I have a NavigationDrawer in this Activity. Now when I press an item in the NavigationDrawer I want my recycler view to refresh accordingly.

In my onCreate:

mRecyclerView = (RecyclerView) findViewById(R.id.detailsList);

Loader:

 ListActivity.this.getLoaderManager().initLoader(0, null, new LoaderManager.LoaderCallbacks<Cursor>() {
            @Override
            public Loader<Cursor> onCreateLoader(int id, Bundle args) {
                return new CursorLoader(ListActivity.this, EmployeeContentProvider.URI_EMPLOYEES, Employee.FIELDS, null, null, Employee.COL_NAME);
            }

            @Override
            public void onLoadFinished(Loader<Cursor> loader, Cursor mCur) {

                if (mCur != null && mCur.moveToFirst()) {
                    do {

                        EmployeeItem empInstance = new EmployeeItem();
                        empInstance.setCall(mCur.getString(mCur.getColumnIndexOrThrow("mobile")));
                        empInstance.setEmail(mCur.getString(mCur.getColumnIndexOrThrow("email")));
                        empInstance.setEmpID(mCur.getString(mCur.getColumnIndexOrThrow("empid")));
                        empInstance.setImageURL(mCur.getString(mCur.getColumnIndexOrThrow("image")));
                        empInstance.setName(mCur.getString(mCur.getColumnIndexOrThrow("name")));
                        employeeList.add(empInstance);
                    } while (mCur.moveToNext());

                    adapter = new DetailsRecyclerAdapter(ListActivity.this, employeeList);
                    mRecyclerView.setAdapter(adapter);
                }
            }

            @Override
            public void onLoaderReset(Loader<Cursor> arg0) {

            }
        });

The above is working flawless. Now in the onClick of my Navigation Drawer:

@Override
    public void onDrawerItemSelected(View view, int position, String value) {
        Log.d("Department selected: ", value);

        final String selectionArgs = value.trim();

        ListActivity.this.getLoaderManager().restartLoader(0, null, new LoaderManager.LoaderCallbacks<Cursor>() {
            @Override
            public Loader<Cursor> onCreateLoader(int id, Bundle args) {

                return new CursorLoader(ListActivity.this, EmployeeContentProvider.URI_EMPLOYEES, Employee.FIELDS, Employee.COL_DEPARTMENT + " IS ? COLLATE NOCASE", new String[]{selectionArgs}, Employee.COL_NAME);
            }

            @Override
            public void onLoadFinished(Loader<Cursor> loader, Cursor mCur) {

                if (mCur != null && mCur.moveToFirst()) {
                    do {

                        EmployeeItem empInstance = new EmployeeItem();
                        empInstance.setCall(mCur.getString(mCur.getColumnIndexOrThrow("mobile")));
                        empInstance.setEmail(mCur.getString(mCur.getColumnIndexOrThrow("email")));
                        empInstance.setEmpID(mCur.getString(mCur.getColumnIndexOrThrow("empid")));
                        empInstance.setImageURL(mCur.getString(mCur.getColumnIndexOrThrow("image")));
                        empInstance.setName(mCur.getString(mCur.getColumnIndexOrThrow("name")));
                        employeeList.add(empInstance);
                    } while (mCur.moveToNext());

                    adapter = new DetailsRecyclerAdapter(ListActivity.this, employeeList);
                    mRecyclerView.setAdapter(adapter);

                    System.out.println("restarted loader");
                }
            }

            @Override
            public void onLoaderReset(Loader<Cursor> arg0) {
                System.out.println("reset loader");
            }
        });
    }

In the above I think the loader is executing as I get the System.out logs, but my RecyclerView does not refresh. What am I missing here? My DB is bridged with a content provider and I have set the selection and selection args properly.

Below are the relevant parts of my ContentProvider:

  @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {

        System.out.println("Provider"+selection+selectionArgs);
        Cursor result = null;
        if (URI_EMPLOYEES.equals(uri)) {
            result = DatabaseHandler
                    .getInstance(getContext())
                    .getReadableDatabase()
                    .query(Employee.TABLE_NAME, Employee.FIELDS, selection, selectionArgs, null, null, Employee.COL_NAME, null);

            result.setNotificationUri(getContext().getContentResolver(), URI_EMPLOYEES);
        } else if (uri.toString().startsWith(EMPLOYEE_BASE)) {
            final long id = Long.parseLong(uri.getLastPathSegment());
            result = DatabaseHandler
                    .getInstance(getContext())
                    .getReadableDatabase()
                    .query(Employee.TABLE_NAME, Employee.FIELDS,
                            Employee.COL_ID + " IS ?",
                            new String[]{String.valueOf(id)}, null, null,
                            null, null);
            result.setNotificationUri(getContext().getContentResolver(), URI_EMPLOYEES);
        } else {
            throw new UnsupportedOperationException("Not yet implemented");
        }

        return result;
    }
User3
  • 2,465
  • 8
  • 41
  • 84
  • 1
    why dont you use something like [this](https://gist.github.com/Shywim/127f207e7248fe48400b) ? – pskink Oct 14 '15 at 09:14
  • @pskink while I appreciate your suggestion, but I have deadlines to follow and I can't change the model now. However it would be great if you suggest something about why the loader is failing to update the recycler view :) – User3 Oct 14 '15 at 09:16
  • your model is perfectly fine, your adapter is not – pskink Oct 14 '15 at 09:17
  • 1
    @User3 ... you know that it will create new adapter instance on every insert/update/delete on URI_EMPLOYEES ? ... seriously, use the code from psink comment – Selvin Oct 14 '15 at 09:19
  • I understand this, however I fail to understant what the Android engineers whre upto when they did not provide Cursor support for Recycler view! Utter disgust! – User3 Oct 14 '15 at 09:21
  • 1
    @User3 me too ... that's i'm stick with ListView/ListFragment ... – Selvin Oct 14 '15 at 09:23
  • and if you want even more simple form of adapter you can use [this](https://gist.github.com/quanturium/c8aa0599a3f984036525), it is like `SimpleCursorAdapter` for a `ListView` – pskink Oct 14 '15 at 09:53
  • What are the tradeoffs if I stick to the approach I have used? I only have to clear the ArrayList and assign a fresh array list? The reason being the pain I have endured in creating this thing and a byproduct of changing my search methods as well. Something like `List employeeList1; employeeList1 = new ArrayList<>();` in the onLoadFinished? But then again I have to change my Search logic again! – User3 Oct 14 '15 at 10:01
  • See this http://stackoverflow.com/questions/15422120/notifydatasetchange-not-working-from-custom-adapter. You will get your answer. You will have to re assing data in that adapter and call notifyDataSetChanged. – Pranjal Sahu Oct 14 '15 at 10:10
  • and it seems that "search / filtering" is done by you in "not android like" way... are you using `Filterable` / `Filter` classes? – pskink Oct 14 '15 at 10:24
  • Yes I am using a filter, I think employeeList.clear() can also solve my issue, however I am assigning the adapter again and again this way - bad practice! – User3 Oct 14 '15 at 10:25
  • so if you are using a `Filter` you can use `setFilterQueryProvider`, that's all, see [here](https://codeshare.io/aFQT7) how easily you can filter out the standard `ListView` using a `FilterQueryProvider`, you need READ_CONTACTS manifest permission for it to work – pskink Oct 14 '15 at 10:27
  • I have used it before with a listview, time constriant brother time constriant! I hate the fact that Cursor support was not given to recycler view – User3 Oct 14 '15 at 10:38
  • there is no Cursor support for a `ListView` as well, but there is a `CursorAdapter`, and i already gave you a `CursorAdapter` for a `RecyclerView`, so what is the issue? – pskink Oct 14 '15 at 10:42
  • Okay, why dont you try being a motivator? I am changing this to use a CursorAdapter type of a thing now. – User3 Oct 14 '15 at 10:44
  • and you even have a `SimpleCursorAdapter` equivalent... so no need to implement an abstract class – pskink Oct 14 '15 at 10:45

0 Answers0