java - initloader - loaders en android
Refrescando una vista dentro de un fragmento (5)
No intente llamar
onCreateView()
usted mismo ... es un método de ciclo de vida y debe ser llamado solo por el marco.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 laActivity
con el funcionamiento interno de unFragment
, ya que el comportamiento delFragment
debe ser independiente e independiente de cualquierActivity
particular.Dicho esto, creo que la mejor solución es hacer que cada uno de tus
Fragment
implemente laLoaderManager.LoaderCallbacks<D>
. CadaFragment
inicializará unLoader
(es decir, unCursorLoader
si está utilizandoContentProvider
respaldado por una base de datos SQLite), y eseLoader
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 aonLoadFinished()
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).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.