0

I have a Loader class, which loads some data asynchronously in an fragment in a RecyclerView. This works fine, when the user comes to that fragment the first time. If he moves away by clicking an ActionBar Button to insert some new data, and returns, I want that the new data becomes visible in my RecyclerView, but it doesn't.

I initialise the Loader in onStart() and although onStart() is called when the user comes back, the loader is not not updating (No changes to the RecyclerView visible)

Here are the relevant methods from the fragment with the loader:

private static final int TERMIN_LOADER_ID = 1;
private static final int AUFGABEN_LOADER_ID = 2;

@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
    switch(i){
        case TERMIN_LOADER_ID:
            return new TerminLoader(getActivity());
        case AUFGABEN_LOADER_ID:
            throw new UnsupportedOperationException("AUFGABEN_LOADER_ID not implemented yet.");
        default:
            throw new UnsupportedOperationException("Unknown loader id.");
    }
}

@Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {

    // mAdapter is a CursorAdapter
    //mAdapter.swapCursor(cursor);
    switch(cursorLoader.getId()){
        case TERMIN_LOADER_ID:
            RadListView termineListView = (RadListView)getActivity().findViewById(R.id.termineRadListView);

            // now here we can fill our termineListView because we got the cursor ready
            ArrayList<Termin> termine = new ArrayList<>();
            cursor.moveToFirst();
            while(!cursor.isAfterLast()){
                // loop over the results from the query and build our termine ArrayList
                // this is our MatrixCursor from our TerminLoader
                long terminId = cursor.getLong(cursor.getColumnIndex(CalendarContract.Events._ID));
                String title = cursor.getString(cursor.getColumnIndex(CalendarContract.Events.TITLE));
                long begin = cursor.getLong(cursor.getColumnIndex(CalendarContract.Events.DTSTART));
                Termin termin = new Termin(terminId, title, begin);
                termine.add(termin);
                cursor.moveToNext();
            }
            TerminListViewAdapter terminListViewAdapter = new TerminListViewAdapter(termine, getActivity());
            termineListView.setAdapter(terminListViewAdapter);

            break;
        case AUFGABEN_LOADER_ID:
            throw new UnsupportedOperationException("AUFGABEN_LOADER_ID not implemented yet.");
        default:
            throw new UnsupportedOperationException("Unknown LOADER_ID.");

    }

}

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

    switch(cursorLoader.getId()){
        case TERMIN_LOADER_ID:
            // now here we can fill our termineListView because we got the cursor ready

            //RadListView termineListView = (RadListView)getActivity().findViewById(R.id.termineRadListView);
            ArrayList<Termin> termine = new ArrayList<>();

            TerminListViewAdapter terminListViewAdapter = new TerminListViewAdapter(termine, getActivity());
            this.termineListView.setAdapter(terminListViewAdapter);

            break;
        case AUFGABEN_LOADER_ID:
            throw new UnsupportedOperationException("AUFGABEN_LOADER_ID not implemented yet.");
        default:
            throw new UnsupportedOperationException("Unknown LOADER_ID.");

    }
}



@Override
public void onStart() {
    super.onStart();
    loadData();
}

public void loadData(){
    // reload termine
    getActivity().getSupportLoaderManager().initLoader(TERMIN_LOADER_ID, null, this);

}

This is how the user moves away:

toolbarBottom = (Toolbar) getActivity().findViewById(R.id.toolbar_bottom);
    toolbarBottom.inflateMenu(R.menu.menu_toolbar_home);
    toolbarBottom.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
        @Override
        public boolean onMenuItemClick(MenuItem menuItem) {
            // the selected patient's id
            SharedPreferences prefs = HomeFragment.this.getActivity().getSharedPreferences(Constants.SHARED_PREFS_FILE, 0);
            long _id = prefs.getLong(Constants.SELECTED_PATIENT_ID, 1);
            switch (menuItem.getItemId()) {
                case R.id.item_termin_erstellen:
                    //Toast.makeText(getActivity(), "Termin clicked: " + String.valueOf(_id), Toast.LENGTH_LONG).show();

                    TerminFragment terminFragment = TerminFragment.newInstance(_id);
                    Bundle args = new Bundle();
                    args.putString(Constants.ACTION, Constants.CREATE);
                    terminFragment.setArguments(args);

                    FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
                    fragmentManager.beginTransaction().replace(R.id.content_frame, terminFragment).addToBackStack(Constants.TERMIN_FRAGMENT).commit();

                    break;
                case R.id.item_aufgabe_erstellen:
                    Toast.makeText(getActivity(), "Aufgabe clicked: " + String.valueOf(_id), Toast.LENGTH_LONG).show();

                    break;
                case R.id.item_dokumentation:
                    Toast.makeText(getActivity(), "Dokumentation clicked: " + String.valueOf(_id), Toast.LENGTH_LONG).show();

                    break;
                default:
            }
            return true;
        }
    });
}

And this is the code in TerminFragment which gets the user back to the first fragment:

    MainActivity mainActivity = (MainActivity) getActivity();
    FragmentManager fragmentManager = getFragmentManager();
    HomeFragment homeFragment = (HomeFragment)fragmentManager.findFragmentByTag(Constants.HOME_FRAGMENT);
    if(homeFragment != null){
        homeFragment.loadData();
    }
    fragmentManager.popBackStack();

And finally, this is my Loader class:

public class TerminLoader extends CursorLoader {
private static final String TAG = "TerminLoader";
private Context context;
// This loader loads events by querying the database for additional data


public TerminLoader(Context context) {
    super(context);
    this.context = context;
}

@Override
public Cursor loadInBackground() {
    // we query against the calendar database for all termine of a peticular patient// only fetch the termine of a particular patient
    SharedPreferences prefs = context.getSharedPreferences(Constants.SHARED_PREFS_FILE, 0);
    long selectedPatientId = prefs.getLong(Constants.SELECTED_PATIENT_ID, 1);
    String selection = TerminContract.Columns.PATIENT_ID + " = ? ";
    String[] selectionArgs = {String.valueOf(selectedPatientId)};
    Cursor cursor = context.getApplicationContext().getContentResolver().query(TerminContract.CONTENT_URI, null, selection, selectionArgs, "");
    cursor.moveToFirst();
    String[] columnNames = {CalendarContract.Events._ID,
        CalendarContract.Events.TITLE,
        CalendarContract.Events.DTSTART};
    MatrixCursor matrixCursor = new MatrixCursor(columnNames);
    while(!cursor.isAfterLast()){
        long terminId = cursor.getLong(cursor.getColumnIndex(TerminContract.Columns.TERMIN_ID));
        // retrieve the event for this terminId by querying the calendar
        Cursor cur = null;
        Uri uri = CalendarContract.Events.CONTENT_URI;
        ContentResolver cr = context.getContentResolver();
        String[] projection2 = {CalendarContract.Events.TITLE,
                CalendarContract.Events.DTSTART};
        String selection2 = "(" + CalendarContract.Events._ID + " = ?)";
        String[] selectionArgs2 = new String[] {String.valueOf(terminId)};
        // Submit the query and get a Cursor object back.
        cur = cr.query(uri, projection2, selection2, selectionArgs2, null);
        cur.moveToFirst();
        // Get the field values
        String title = cur.getString(cur.getColumnIndex(CalendarContract.Events.TITLE));
        //String title = "title";
        long dtStart = cur.getLong(cur.getColumnIndex(CalendarContract.Events.DTSTART));

        // and add it to our MatrixCursor
        MatrixCursor.RowBuilder rowBuilder = matrixCursor.newRow();
        rowBuilder.add(terminId)
            .add(title)
            .add(dtStart);

        //move to nexr row
        cursor.moveToNext();
    }
    return matrixCursor;
}

}

Any ideas? Note, that I can confirm that before the above lines are executed, the data is inserted correctly. Also note, that the above lines fail to findFragmentByTag.

Thanks

mrd
  • 4,561
  • 10
  • 54
  • 92

1 Answers1

0

I fixed the problem by a very simple, little change:

public void loadData(){
    // reload termine
    getActivity().getSupportLoaderManager().destroyLoader(TERMIN_LOADER_ID);
    getActivity().getSupportLoaderManager().initLoader(TERMIN_LOADER_ID, null, this);

}

I destroy an existing loader before initialising the loader.

mrd
  • 4,561
  • 10
  • 54
  • 92