2012-01-30 12 views
10

En el example 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.¿Está bien para actualizar fragmentos en lugar de crear nuevas instancias?

¿Es esta la 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í misma. 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 a lo largo de las líneas de DetailsFragment.setShownIndex(). Esto se llamaría, pasando el nuevo índice del título, en lugar de recrear 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 títulos está en resumed estado (es decir, en el 'plano'), la selección de un título resultará en una llamada a DetailsFragment.setShownIndex() en un momento en el fragmento detalles es en stopped estado.

¿Buena idea? ¿Mala idea?

Gracias de antemano.

Respuesta

5

Como dijo, 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()). Algunas veces necesitará hacer un buen uso de los métodos de Fragment como isVisible(), isRemoving() etc. para no hacer referencia ilegal a los componentes UI cuando el DetailsFragment es stopped.

todos modos en su actividad de un solo panel propuesto con 2 fragmentos, su método de setShownIndex podría establecer un campo privado en DetailsFragment que se carga en onCreateView o onActivityCreated.

por ejemplo,

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 crea nuevamente o reutilizado, onCreateView y onActivityCreated se llamará cuando el DetailsFragment se agrega al recipiente.

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

0

He probado 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 ejecutar 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 poder ayudarte

+0

sería más útil si proporcionó comentarios en inglés –

+0

Lo siento.Yo soy italiano. –

Cuestiones relacionadas