Fragmentos no funcionan correctamente después de cambio de orientación
Tengo un problema con Fragments
y cambio de orientación.
Tengo una aplicación que tiene una MainActivity
que maneja la conmutación de Fragments
través de una barra de acción con pestañas. Aquí está el código de la barra de acción con pestañas y cuando se selecciona una pestaña.
- ¿Por qué estoy obteniendo una referencia nula en mi RecyclerView
- Utilizar OnItemClickListener en ListView dentro de ViewPager
- cómo cerrar un fragmento al tirar hacia arriba o hacia abajo?
- En una actividad tabulada con ViewPager, el ListView aparece cortado desde la parte inferior
- IllegalStateException: La actividad se ha destruido - cuando la aplicación está intentando mostrar DialogFragment una vez más
private class MyTabListener <T extends android.support.v4.app.Fragment> implements ActionBar.TabListener { private android.support.v4.app.Fragment mFragment; private final Activity mActivity; private final String mTag; private final Class<T> mClass; public MyTabListener(SherlockFragmentActivity activity, String tag, Class<T> clz) { mActivity = activity; mTag = tag; mClass = clz; } @Override public void onTabSelected(Tab tab, android.support.v4.app.FragmentTransaction ft) { if (mFragment == null){ // check to see if the fragment has already been initialised. If not create a new one. mFragment = android.support.v4.app.Fragment.instantiate(mActivity, mClass.getName()); ft.add(android.R.id.content,mFragment,mTag); } else { ft.attach(mFragment); // if the fragment has been initialised attach it to the current activity } } @Override public void onTabUnselected(Tab tab, android.support.v4.app.FragmentTransaction ft) { if (mFragment != null){ ft.detach(mFragment); // when a fragment is no longer needed, detach it from the activity but dont destroy it } } @Override public void onTabReselected(Tab tab, android.support.v4.app.FragmentTransaction ft) { }
La manera que lo veo es que todo trabaja muy bien cuando la aplicación primero carga en modo del retrato. Cuando roto, por alguna razón se agrega otra instancia de Fragment1
y luego no se desprende cuando se selecciona otra pestaña. Este es también el caso cuando vuelvo a girar de nuevo al retrato.
He intentado usar setRetainInstance(true);
En mis Fragments
pero esto no funciona.
¿Hay un método que necesito para anular o hacer algo con mis Fragments
antes de girar?
Gracias por adelantado.
EDIT Ahora he visto que onTabSelected se llama de nuevo cuando la actividad es recreada. ¿Podría esto ser la causa de mi problema con los fragmentos que se atan más de una vez?
Aquí está mi método onCreate de actividades.
super.onCreate(savedInstanceState); if (savedInstanceState == null) { //setContentView(R.layout.main); } // Create the Action Bar with tabs ActionBar actionBar = getSupportActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); actionBar.setDisplayShowTitleEnabled(false); //create the tab for track and add it to the action bar. Tab tab = actionBar.newTab() .setText("Track") .setTabListener(new MyTabListener<TrackingFragment>(this,"track",TrackingFragment.class)); actionBar.addTab(tab); //create the tab for ski tracks and add it to the action bar. tab = actionBar.newTab() .setText("Something Tracks") .setTabListener(new MyTabListener<TrackListFragment>(this,"somethingtracks",TrackListFragment.class)); actionBar.addTab(tab); //create the tab for photos and add it to the action bar. tab = actionBar.newTab() .setText("Photos") .setTabListener(new MyTabListener<PhotoFragment>(this,"photos",PhotoFragment.class)); actionBar.addTab(tab);
- Creación de pestañas de barra de acción de un fragmento
- Establecer la orientación para sólo 1 fragmento en mi actividad, mientras que el resto está en el retrato
- Cómo obtener fragmentos para ver correctamente
- Determinar el cambio de fragmentos mientras se prueba el espresso
- Deshabilitar la paginación de ViewPager cuando el reciclador de niños se desplaza al último elemento
- Detectar el cambio de la pestaña ViewPager dentro del fragmento
- ID duplicado con fragmento
- No se pudo encontrar la clase 'android.widget.ThemedSpinnerAdapter'
5 Solutions collect form web for “Fragmentos no funcionan correctamente después de cambio de orientación”
Corto arreglo:
En el método onTabSelected
, antes de usar if (mFragment == null)
es necesario intentar obtener el fragmento (usando mFragment = getSupportFragmentManager().findFragmentByTag(mTag)
). También puede establecer esto desde el exterior, pero no te veo haciendo esto.
Comprobar if(savedInstanceState == null)
en onCreate
también podría resolver esto y lo considero un enfoque mejor sin embargo! 🙂
Parece que no tienes algo en tu método onCreate
envuelto en un if(savedInstanceState == null)
, por lo que estás creando otro fragmento además del que está siendo restaurado desde el paquete savedInstanceState.
EDITAR
Mirando más de cerca su código, creo que estaba equivocado sobre el onCreate, su onTabSelected debe manejarlo. Creo que tu if (mFragment == null)
siempre viene nulo, porque no intentas encontrar el fragmento. Cambiar esa sección de código a:
@Override public void onTabSelected(Tab tab, android.support.v4.app.FragmentTransaction ft) { mFragment = mActivity.getSupportFragmentManager().findFragmentByTag(mTag); // add this if (mFragment == null){ // check to see if the fragment has already been initialised. If not create a new one. mFragment = android.support.v4.app.Fragment.instantiate(mActivity, mClass.getName()); ft.add(android.R.id.content,mFragment,mTag); } else { ft.attach(mFragment); // if the fragment has been initialised attach it to the current activity } }
Me enteré de que setRetainInstance
es realmente ignorado y todos los fragmentos creados por el android.support.v4.app.FragmentManager
se almacenan en onSaveInstanceState
y se recrean en onCreate
.
Para mí, la solución fue borrar sin rodeos el fragmento guardado de forma superflua: https://stackoverflow.com/a/13996054/341091
Tuve más o menos el mismo problema, pero las soluciones presentadas anteriormente no parecen funcionar en mi situación. Finalmente encontré la siguiente solución:
@Override public void onTabSelected(Tab tab, FragmentTransaction ft) { if (mFragment == null) { mFragment = Fragment.instantiate(mActivity, mClass.getName()); ft.replace(android.R.id.content, mFragment, mTag); // Use replace iso add } else { ft.attach(mFragment); } }
If (savedInstanceState == null) no está funcionando siempre. A veces savedInstanceState! = Null mientras se necesita agregar otro fragmento debido a la orientación horizontal.
Otra aproximación es probar si fm.findFragmentById (R.id.frameLayoutLeft), no importa cuál sea la orientación, es nulo o no, en caso afirmativo, que crear una nueva instancia de fragmento de otra manera no hacer nada. Si necesita un segundo fragmento en modo horizontal, primero debe comprobar si es horizontal o no, de ser así, compruebe si fm.findFragmentById (R.id.frameLayoutRight) es nulo o no. Si nulo, que crear, de lo contrario no hacer nada porque ya está allí retenido por Android OS.
- Predeterminación de destino en Ant
- Cómo configurar el enfoque en un TextView cuando se inicia una actividad?