39

He desarrollado una aplicación en Honeycomb y estoy usando fragmentos.
Esta es mi aplicaciónConservar el objeto Fragmento mientras rota

  • tengo una Actividad (Say A1) y en el que hay un fragmento de
  • Inicialmente mantenga este fragmento del objeto un objeto fragmento decir (F1)
  • A continuación, en función de la las acciones del usuario se puede cambiar a otros objetos F2, F3 ....

cuál es mi problema

cuando el usuario gira el dispositivo de la actividad se vuelve a crear y que hacen que la F1 como el objeto fragmento a pesar de que antes de girar no era
What is the way to retain the fragment object while rotating?
Solía ​​setRetainInstance(true); pero no funcionó para mí
Y tengo añadió el fragmento de código en mi función como esta onCreate

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); 

    Fragment homeFragment = new Home(); 
    fragmentTransaction.add(R.id.mainFragement, homeFragment); 
    fragmentTransaction.commit(); 
} 

Respuesta

53

por defecto Android retendrá los objetos de fragmentos. En su código está configurando el homeFragment en su función onCreate. Es por eso que siempre es homeFragment o fl lo que establezca en onCreate.

Debido a que cada vez que se gira, onCreate ejecutará y establecer su objeto fragmento de la primera

Así que la solución fácil para usted es comprobar si savedInstanceState paquete es nulo o no y establece el objeto fragmento

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    if(null == savedInstanceState) { 
     // set you initial fragment object 
    } 
} 
+1

¿Qué debo hacer en caso de que utilice un actividad con ViewPager que maneja los fragmentos? –

+0

@androiddeveloper pray. No seriamente lo que hice fue: super.onCreate (null); – Warpzit

+19

"De forma predeterminada, Android retendrá los objetos de fragmento" ... no es cierto. Android creará nuevos objetos en los cambios de orientación, a menos que se llame a 'setRetainInstance (true)'. No confundas esto con Android volviendo a conectar fragmentos automáticamente. No són la misma cosa. Verifique los rastros informados por S.D. en [esta respuesta] (http://stackoverflow.com/a/12641575/2619107). – Rafa

34

Debe darle a su Fragmento una etiqueta única y verificar si este Fragmento ya está agregado a su Actividad o no.

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    String tag = "my_fragment"; 
    FragmentManager fragmentManager = getFragmentManager(); 
    if(fragmentManager.findFragmentByTag(tag) == null) { 
     FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); 
     Fragment homeFragment = new Home(); 
     fragmentTransaction.add(R.id.mainFragement, homeFragment, tag); 
     fragmentTransaction.commit(); 
    } 
} 

comprobar si savedInstanceState es nulo no es una manera segura de comprobar si el fragmento ya está establecido - que funcionará en la mayoría de los casos, pero en algunos casos (por ejemplo, cuando el dispositivo está en la memoria baja), Android puede matar su actividad, lo que podría romper su aplicación.

Para ver esto en acción, marque "No guardar actividades" en las opciones de desarrollo del dispositivo (la configuración está disponible en Android 4.0+, no estoy seguro acerca de las versiones anteriores). Cuando abre una nueva actividad, su primera actividad se destruye. Cuando regresa (al presionar hacia atrás), se crea de nuevo y savedInstanceState es no nulo. Sin embargo, su fragmento ya no está en la actividad y debe agregarlo nuevamente.

EDITAR - Mostrando el principio original pero con SupportFragmentManager

public class ActivityAwesome extends AppCompatActivity 
{ 
    private final String TAG = getClass().getSimpleName(); 
    private FragmentHome mHomeFragment; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_layout); 

     FragmentManager fragmentManager = getSupportFragmentManager(); 
     Fragment fragment = fragmentManager.findFragmentByTag(TAG); 
     if(fragment == null) 
     { 
      // Create the detail fragment and add it to the activity using a fragment transaction. 
      mHomeFragment = new FragmentHome(); 
      fragmentManager.beginTransaction() 
        .add(R.id.fragment_container, mHomeFragment, TAG) 
        .commit(); 
     } 
     else 
     { 
      // get our old fragment back ! 
      mHomeFragment = (FragmentHome)fragment; 
     } 
    } 
} 

Esto viene especialmente útil si se quiere manipular el fragmento (en este caso mHomeFragment) después de girar el dispositivo

+0

Si bien he utilizado la respuesta proporcionada por @labeeb anteriormente, creo que el mejor enfoque es verificar la 'etiqueta' única. –

+0

¡muy interesante! Parece entonces que Google necesita actualizar su código de plantilla. –

0

definí un Fragment en el diseño de la actividad, onSaveInstanceState en el Fragment se llama, pero el savedInstanceStateBundle en el onCreatView del Fragmento viene como nulo.

La razón era que mi Fragment no tienen una identificación en XML:

android:id="@+id/compass_fragment" ... 
3

Uso onAttachFragment() en su Activity Para volver a asignar el objeto:

@Override 
public void onAttachFragment(Fragment fragment) { 
    if (fragment instanceof MyFragment) 
     this.myFragment = (MyFragment) fragment; 
} 
Cuestiones relacionadas