¿Cómo puedo actualizar el cursor desde un CursorLoader?


Así que tengo mi MainDisplayActivity que implementa ambos Activity y LoaderManager.LoaderCallbacks<Cursor>. Aquí tengo un ListView, que lleno con información de la Agenda que obtengo de mi base de datos usando un ContentProvider. También tengo un GridView que es un calendario. Lo tengo configurado al hacer clic en una celda, que la agenda se actualiza con el día en que se hace clic. Mi problema es que cuando reutilizo el Cargador que creé en onCreate() dentro de setOnItemClickListener(), no actualiza la información con el nuevo cursor que estoy creando. Puedo crear un nuevo Cargador con otro ID, y funciona una vez, pero una vez que hago clic otro día, deja de refrescarse. El problema está en el cursor. ¿Cómo puedo actualizar un cursor desde un Cargador para no tener que seguir creando un nuevo Cargador? Gracias de antemano!

Llamada inicial para crear el Loader en onCreate () en Mi clase MainDisplayActivity:

makeProviderBundle(new String[] {"_id, event_name, start_date, start_time, end_date, end_time, location"},
            "date(?) >= start_date and date(?) <= end_date", new String[]{getChosenDate(), getChosenDate()}, null);
    getLoaderManager().initLoader(0, myBundle, MainDisplayActivity.this);

    list.setAdapter(agendaAdapter);

Estos son los métodos anulados de LoaderCallbacks<Cursor>

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    Uri baseUri = SmartCalProvider.CONTENT_URI;
    return new CursorLoader(this, baseUri, args.getStringArray("projection"), 
            args.getString("selection"), args.getStringArray("selectionArgs"), args.getBoolean("sortOrder") ? args.getString("sortOrder") : null );
}



@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) {
    agendaAdapter.swapCursor(arg1);
}



@Override
public void onLoaderReset(Loader<Cursor> arg0) {
    //Not really sure how this works. Maybe I need to fix this here?
    agendaAdapter.swapCursor(null);

}

public void makeProviderBundle(String[] projection, String selection, String[] selectionArgs, String sortOrder){
    /*this is a convenience method to pass it arguments 
     * to pass into myBundle which in turn is passed 
     * into the Cursor loader to query the smartcal.db*/
    myBundle = new Bundle();
    myBundle.putStringArray("projection", projection);
    myBundle.putString("selection", selection);
    myBundle.putStringArray("selectionArgs", selectionArgs);
    if(sortOrder != null) myBundle.putString("sortOrder", sortOrder);
}

Cualquier código adicional necesario por favor no dude en preguntar. Gracias de nuevo por cualquier ayuda!

Author: Pi Delport, 2012-06-19

1 answers

Solo necesita mover su código un poco y llamar a restartLoader. Es decir,

  1. Cuando el usuario hace clic en un elemento de lista, de alguna manera cambia la variable de instancia privada que se devuelve en getChosenDate() (estoy siendo intencionalmente vago aquí porque no especificó qué devuelve exactamente getChosenDate()).

  2. Una vez realizado el cambio, llame a getLoaderManager().restartLoader() en su Loader. Sus datos antiguos serán descartados y restartLoader activará onCreateLoader para ser llamados de nuevo. Esta vez, getChosenDate() devuelve un valor diferente (dependiendo del elemento de la lista en el que se hizo clic) y eso debería hacerlo. Su onCreateLoader implementación debería ser algo como esto:

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        Uri baseUri = SmartCalProvider.CONTENT_URI;
    
        makeProviderBundle(
            new String[] { "_id, event_name, start_date, start_time, end_date, end_time, location" },
            "date(?) >= start_date and date(?) <= end_date", 
            new String[]{ getChosenDate(), getChosenDate() }, 
            null);
    
        return new CursorLoader(
                this, 
                baseUri, 
                args.getStringArray("projection"), 
                args.getString("selection"), 
                args.getStringArray("selectionArgs"),    
                args.getBoolean("sortOrder") ? args.getString("sortOrder") : null);
    }
    

Hazme saber si eso tiene sentido. :)

 40
Author: Alex Lockwood,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-19 00:23:48