configchanges - on rotate android
Retenga el objeto Fragment mientras rota (5)
Desarrollé una aplicación en Honeycomb y estoy usando fragmentos.
Esta es mi aplicación
- Tengo una actividad (decir A1) y en eso hay un fragmento
- Inicialmente, este fragmento contiene el objeto que dice un objeto fragmento (F1)
- Luego, dependiendo de las acciones del usuario, puede cambiar a otros objetos F2, F3 ...
Cual es mi problema
Cuando el usuario gira el dispositivo, se recrea la actividad y hace que F1 sea el objeto de fragmento aunque antes de rotarlo no era
What is the way to retain the fragment object while rotating?
setRetainInstance(true);
pero no funcionó para mí
Y he agregado el fragmento por código en mi función onCreate
como esta
@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();
}
De forma predeterminada, Android retendrá los objetos de fragmento. En su código está configurando homeFragment
en su función onCreate
. Es por eso que siempre hay algún homeFragment
o cualquier homeFragment
que establezca en onCreate
.
Porque cada vez que gira, el onCreate se ejecutará y establecerá su objeto de fragmento al primero
Entonces, la solución más fácil para usted es verificar si el paquete savedInstanceState
es nulo o no y configurar el objeto fragmento
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(null == savedInstanceState) {
// set you initial fragment object
}
}
Necesitas darle a tu Fragmento una etiqueta única y verificar si este Fragmento ya está agregado a tu 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 forma segura de verificar si su fragmento ya está configurado: funcionará en la mayoría de los casos, pero en algunos casos (como cuando el dispositivo tiene poca memoria), Android puede matar su actividad, lo que podría rompe tu 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 no es 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 es especialmente útil si desea manipular el fragmento (en este caso mHomeFragment
) después de rotar su dispositivo
Simplemente puede establecer la propiedad RetainInstance
dentro de OnCreate
de la clase de fragmento.
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
RetainInstance = true;
}
Utilice onAttachFragment()
en su Activity
para reasignar el objeto:
@Override
public void onAttachFragment(Fragment fragment) {
if (fragment instanceof MyFragment)
this.myFragment = (MyFragment) fragment;
}
onSaveInstanceState
un Fragment
en el diseño de la actividad, onSaveInstanceState
en el Fragment
se llama, pero el Bundle
savedInstanceState
en savedInstanceState
del Fragmento viene como nulo.
El motivo fue que mi Fragment
no tenía una identificación en XML:
android:id="@+id/compass_fragment" ...