studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones android android-activity transactions lifecycle fragment

para - manual de programacion android pdf



Ok, ¿actualizar los fragmentos en lugar de crear nuevas instancias? (2)

En el ejemplo sobre el uso de fragmentos en los documentos de Android, cuando la aplicación está en modo ''dualview'', el fragmento de detalles se recrea cada vez que la aplicación necesita mostrar detalles para un título diferente. FragmentTransaction.replace() se usa para intercambiar cada instancia de fragmento de detalles anterior por una nueva.

¿Es esta práctica recomendada? ¿No es un desperdicio crear una nueva instancia de UI cuando la verdadera intención (sin juego de palabras) es actualizar lo que muestra la interfaz de usuario, no la interfaz de usuario en sí. Me parece que la única razón para crear nuevas instancias es si se pretende agregarlas a la backstack para que el usuario pueda seguir los pasos. De lo contrario, ¿es seguro / aconsejable actualizar un fragmento directamente?

En el caso del ejemplo, significaría un método en la línea de DetailsFragment.setShownIndex() . Esto se llamaría, pasando el nuevo índice del título, en lugar de volver a crear DetailsFragment .

Supongamos que tenemos una versión del ejemplo donde una actividad administra ambos fragmentos, pero solo muestra uno a la vez, intercambiando cada fragmento según sea necesario. ¿Sería correcto para la actividad crear una instancia de cada fragmento, retener las referencias a cada uno, y luego simplemente agregar o eliminar estas dos instancias de sí mismo según sea necesario?

Una consecuencia posiblemente pegajosa de esto sería que, cuando el fragmento de los títulos está en estado resumed (es decir, en el "primer plano"), al seleccionar un título se producirá una llamada a DetailsFragment.setShownIndex() en el momento en que se encuentra el fragmento de detalles estado stopped .

¿Buena idea? ¿Mala idea?

Gracias por adelantado.


Como dijiste, la razón principal para crear nuevas instancias de Fragment es para facilitar el uso de la pila de respaldo. También es perfectamente seguro reutilizar un Fragmento existente (buscándolo con FragmentManager.findFragmentById() o FragmentManager.findFragmentByTag() ). A veces necesitará hacer un buen uso de los métodos de Fragment como isVisible() , isRemoving() etc. por lo que no hace referencias ilegales a los componentes de la UI cuando se stopped el DetailsFragment .

De todos modos, en su Actividad de panel único propuesta con 2 fragmentos, su método setShownIndex podría establecer un campo privado en DetailsFragment que se carga en onCreateView o onActivityCreated .

p.ej,

DetailsFragment df = getFragmentManager().findFragmentByTag("details"); if (df != null) { df.setShownIndex(getSelectedIndex()); } else { df = DetailsFragment.newInstance(getSelectedIndex()); } fragmentTransaction.replace(R.id.frame, df, "details").commit();

En ambos casos, si df se acaba de crear o se reutiliza, se onCreateView y onActivityCreated cuando el onCreateView onActivityCreated se agregue al contenedor.

Pero si quieres una pila de respaldo, te recomiendo que solo crees nuevas instancias, de lo contrario solo estás implementando tu propia pila de respaldo para el contenido de DetailsFragment .


He intentado con el siguiente código y funciona para mí:

private void replaceFragment(Class fragmentClass, String FRAGMENT_NAME, android.support.v4.app.FragmentManager fragmentManager) { Fragment fragment = null; String backStateName = fragmentClass.getName(); // nome della classe del Fragment Log.d("Fragment: ", "Creazione Fragment: "+backStateName); Boolean fragmentExit = isFragmentInBackstack(fragmentManager, backStateName); if (fragmentExit) { //Il Fragment è presente nello stacback // Fragment exists, go back to that fragment //// you can also use POP_BACK_STACK_INCLUSIVE flag, depending on flow fragmentManager.popBackStackImmediate(fragmentClass.getName(), 0); } else { // se non esiste lo aggiungiamo try { fragment = (Fragment) fragmentClass.newInstance(); } catch (Exception e) { e.printStackTrace(); } // Inizializzo la transazione del Fragment android.support.v4.app.FragmentTransaction ft = fragmentManager.beginTransaction(); ft.setCustomAnimations( R.anim.fragment_slide_left_enter, R.anim.fragment_slide_left_exit, R.anim.fragment_slide_right_enter, R.anim.fragment_slide_right_exit); ft.replace(R.id.frameLayout_contentMain, fragment, FRAGMENT_NAME); ft.addToBackStack(fragmentClass.getName()); ft.commit(); // Recupero il numero di Fragment presenti Integer nFragment = fragmentManager.getBackStackEntryCount(); Log.d("Fragment: ", "Numero di Fragment: "+nFragment); } }

Para determinar si el Fragmento ya está en StackBack, ejecute esta función:

public static boolean isFragmentInBackstack(final android.support.v4.app.FragmentManager fragmentManager, final String fragmentTagName) { for (int entry = 0; entry < fragmentManager.getBackStackEntryCount(); entry++) { if (fragmentTagName.equals(fragmentManager.getBackStackEntryAt(entry).getName())) { return true; } } return false; }

Espero que te pueda ayudar