oncreateloader loaders initloader getloadermanager cursorloader java android android-fragments android-view android-loadermanager

java - initloader - loaders en android



Refrescando una vista dentro de un fragmento (5)

  1. No intente llamar onCreateView() usted mismo ... es un método de ciclo de vida y debe ser llamado solo por el marco.

  2. Fragment son componentes de UI reutilizables. Tienen su propio ciclo de vida, muestran su propia vista y definen su propio comportamiento. Por lo general, no es necesario que el desorden de la Activity con el funcionamiento interno de un Fragment , ya que el comportamiento del Fragment debe ser independiente e independiente de cualquier Activity particular.

    Dicho esto, creo que la mejor solución es hacer que cada uno de tus Fragment implemente la LoaderManager.LoaderCallbacks<D> . Cada Fragment inicializará un Loader (es decir, un CursorLoader si está utilizando ContentProvider respaldado por una base de datos SQLite), y ese Loader estará a cargo de (1) cargar los datos en un hilo de fondo y (2) escuchar cambios de contenido que se hacen a la fuente de datos y entregan nuevos datos a onLoadFinished() cada vez que ocurre un cambio de contenido.

    Esta solución es mejor que su solución actual porque está completamente controlada por eventos. Solo necesita actualizar la vista cuando los datos se entregan en onLoadFinished() (en lugar de tener que verificar manualmente si la fuente de datos se ha cambiado cada vez que hace clic en una pestaña nueva).

  3. Si eres perezoso y solo quieres una solución rápida, es posible que puedas salir con la actualización de la vista en el método onResume() Fragment .

He buscado las numerosas preguntas que se parecen a esta, pero no he encontrado mi respuesta en ninguna de ellas.

Tengo una actividad que tiene 3 pestañas accesibles a través de la barra de acciones. Logré esto agregando 3 fragmentos que inflan una vista personalizada que hice ampliando la clase de vista.

En el momento en que cambia la base de datos, trato de actualizar la vista en mi pestaña llamando a invalidate () / postinvalidate (), pero esto no funciona. Lo mismo es cierto para llamar aCreateView del fragmento al igual que muchas otras opciones que consideré.

Sin embargo, cuando voy a otra pestaña y regreso, el cambio se ha realizado y mi vista se actualiza como debería.

¿Cómo puedo simular lo mismo que sucede cuando cambio a otra pestaña? Qué sucede Traté de ver el ciclo de vida de Fragment (intenté llamar aCreateView ()) para resolverlo, pero simplemente no desea actualizar / volver a dibujar como debería.

Los datos se cargan correctamente, ya que los datos se cambian cuando cambio a otra pestaña.

Eliminé parte del código porque ya no es relevante. Implementé Cursorloaders en lugar de mi propio patrón Observer para notificar un cambio. Esta es mi actividad principal en este momento.

La pregunta es: ¿qué debo hacer ahora si quiero volver a dibujar la vista dentro de estos fragmentos? Si aplico fragmentObject.getView (). Invalidate () no funciona. Estoy teniendo el mismo problema que antes, pero ahora mi Observer para notificar un cambio en la base de datos se implementa correctamente con los cargadores.

public class ArchitectureActivity extends Activity implements LoaderManager.LoaderCallbacks<Cursor> { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ActionBar actionbar = getActionBar(); actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); ActionBar.Tab EditTab = actionbar.newTab().setText("Edit"); ActionBar.Tab VisualizeTab = actionbar.newTab().setText("Visualize"); ActionBar.Tab AnalyseTab = actionbar.newTab().setText("Analyse"); Fragment editFragment = new EditFragment(); Fragment visualizeFragment = new VisualizeFragment(); Fragment analyseFragment = new AnalyseFragment(); EditTab.setTabListener(new MyTabsListener(editFragment)); VisualizeTab.setTabListener(new MyTabsListener(visualizeFragment)); AnalyseTab.setTabListener(new MyTabsListener(analyseFragment)); actionbar.addTab(EditTab); actionbar.addTab(VisualizeTab); actionbar.addTab(AnalyseTab); ArchitectureApplication architectureApplication = (ArchitectureApplication)getApplicationContext(); architectureApplication.initialize(); getLoaderManager().initLoader(0, null, this); getLoaderManager().initLoader(1, null, this); } public Loader<Cursor> onCreateLoader(int id, Bundle args) { if (id == 0){ return new CursorLoader(this, GraphProvider.NODE_URI , null, null, null, null); } else if (id == 1){ return new CursorLoader(this, GraphProvider.ARC_URI , null, null, null, null); } return null; } public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { // Reloading of data, actually happens because when switching to another tab the new data shows up fine Log.e("Data", "loaded"); } public void onLoaderReset(Loader<Cursor> loader) { } }


He encontrado una solución para actualizar la vista dentro de mi fragmento. Recreé (nueva vista personalizada) la vista cada vez que se actualizó la base de datos. Después de eso, invoco setContentView (vista CustomView). Se parece más a un truco, pero funciona y nada más lo intenté.

Aunque mi problema no fue resuelto, le di la recompensa a Alex Lockwood. Su consejo sobre los cargadores mejoró mi aplicación y me hizo seguir buscando una solución que finalmente encontré.


La solución más rápida que funciona para mí:

@Override public void onPause() { super.onPause(); if (isRemoving() && fragmentView != null) { ((ViewGroup) fragmentView).removeAllViews(); } }


Tuve el mismo problema. Mi solución fue separar el fragmento y adjuntarlo de nuevo.

FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); Fragment f = getFragment(action); if(forceUpdate) { fragmentTransaction.detach(f); fragmentTransaction.attach(f); } fragmentTransaction.replace(R.id.mainFragment, f); fragmentTransaction.commit(); currentAction = action;


Tuve un problema similar (aunque no idéntico) que pude resolver de la siguiente manera:

En el fragmento que agregué

public void invalidate() { myView.post(new Runnable() { @Override public void run() { myView.invalidate(); } }); }

y llamé a este método de la actividad cuando quería actualizar la vista myView del fragmento. El uso de post () garantiza que la vista solo se invalide cuando esté lista para dibujarse.