¿Cómo mantener el estado del fragmento sin backstack en la pestaña?

Estoy intentando ahorrar el estado del fragmento en onSaveInstanceState pero cuando vuelvo al fragmento, siempre recargado otra vez en vez de comenzar del estado pasado.

Miré en onCreateView y onActivityCreated y siempre tiene onSaveInstanceState como null.

 public void navigateFragment(String tag, Fragment fragment, boolean shouldAdd) { FragmentManager manager = getSupportFragmentManager(); FragmentTransaction ft = manager.beginTransaction(); if (shouldAdd) mStacks.get(tag).push(fragment); // push fragment on stack ft.replace(android.R.id.tabcontent, fragment); if (shouldAdd) ft.addToBackStack(tag); ft.commit(); } 

Como soy incapaz de usar backstack porque en las pestañas de la pila de atrás no es útil. Cualquier ayuda sería muy apreciada.

En este caso usted tiene que manejar estados de los fragmentos por se. No sé exactamente cómo funciona su código, por lo que lo único que puedo hacer es darle algunas pistas.

Lo primero que necesita implementar es guardar el estado del fragmento. Supongamos que todos los fragmentos tienen identificadores únicos. En este caso es necesario crear un mapa que mantenga todos los estados:

 private final Map<String, Fragment.SavedState> mFragmentStates = new HashMap<>(); private void saveFragmentState(String id, Fragment fragment) { Fragment.SavedState fragmentState = getSupportFragmentManager().saveFragmentInstanceState(fragment); mFragmentStates.put(id, fragmentState); } 

Debe llamar a este método para un fragmento que va a eliminar. Entonces necesitamos restaurar el estado del fragmento y así es como podemos hacerlo:

 private void restoreFragmentState(String id, Fragment fragment) { Fragment.SavedState fragmentState = mFragmentStates.remove(id); if (fragmentState != null) { fragment.setInitialSavedState(savedState); } } 

Este método necesita llamar antes de agregar un fragmento a una transacción.

El código proporcionado debe funcionar bien, pero para que funcione correctamente en la recreación de la actividad que tenemos que guardar y restaurar mFragmentStates correctamente:

 private static final String KEY_FRAGMENT_STATES = "fragment_states"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /* Your code ... */ if (savedInstanceState != null) { Bundle fragmentStates = savedInstanceState.getParcelable(KEY_FRAGMENT_STATES); if (fragmentStates != null) { for (String id : fragmentStates.keySet()) { Fragment.SavedState fragmentState = fragmentStates.getParcelable(id); mFragmentStates.put(id, fragmentState); } } } } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); /* Your code ... */ Bundle fragmentStates = new Bundle(mFragmentStates.size()); for (Map.Entry<String, Fragment.SavedState> entry : mFragmentStates.entrySet()) { fragmentStates.put(entry.getKey(), entry.getValue()); } outState.putParcelable(KEY_FRAGMENT_STATES, fragmentStates); } 

También puedes echar un vistazo a la clase FragmentStatePagerAdapter . Utiliza el mismo enfoque para gestionar estados de ViewPager de ViewPager .

ACTUALIZACIÓN : Y por lo tanto su código debería terminar buscando algo como esto:

 private Fragment mCurrentFragment; public void navigateFragment(String tag, Fragment fragment, boolean shouldAdd) { FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); if (shouldAdd) { mStacks.get(tag).push(fragment); // push fragment on stack } if (mCurrentFragment != null) { saveFragmentState(mCurrentFragment.getClass().getName(), mCurrentFragment); } mCurrentFragment = fragment; restoreFragmentState(fragment.getClass().getName(), fragment); transaction.replace(android.R.id.tabcontent, fragment); if (shouldAdd) { // You shouldn't use back-stack when managing fragment states by yourself. transaction.addToBackStack(tag); } transaction.commit(); } 

En este ejemplo, utilizo el nombre de clase de fragmento como un id, de modo que todo el fragmento debe tener clases diferentes. Pero puede utilizar cualquier otro valor único como ID. Y otra cosa importante que tengo que mencionar es que no debes usar back-stack cuando manejes estados de fragmentos por ti mismo. Back-stack realiza una administración de estado similar y es probable que tenga conflictos.

Creo que deberías usar la idea de Preferencias Compartidas , esto es más rápido que usar archivos locales o bases de datos, y definitivamente más fácil de codificar. Una buena página web para Android @ Opciones de almacenamiento . Voy a poner algún código de ejemplo de la página web y cambiar unos pocos para adaptarse a sus necesidades.

Primero, obtenga los datos guardados de las preferencias en el método de sustitución onCreate ():

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); boolean silent = settings.getBoolean("silentMode", false); ... } 

A continuación guardemos los datos antes de que el fragmento se detenga o salga, por varias razones. Conseguir esto mediante el método override onDetach , la sustitución de la página web onStop() .

 @Override public void onDetach() { super.onDetach(); ... SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); SharedPreferences.Editor editor = settings.edit(); editor.putBoolean("silentMode", mSilentMode); // Commit the edits! editor.commit(); } 

¡Buena suerte, diviértete!

Usted está haciendo el reemplazo del fragmento, thats porqué el fragmento está consiguiendo destruido. Puedes probar abajo. Aquí estoy haciendo dos cosas en FragmentTransaction único, estoy agregando un nuevo fragmento y ocultar el fragmento existente.

Digamos que estamos agregando el fragmento B en la parte superior del fragmento A

  FragmentTransaction ft = fragmentManager.beginTransaction(); ft.add(android.R.id.tabcontent, fragmentB, tagFragmentB) .hide(fragmentManager.findFragmentByTag(tagFragmentA)) .addToBackStack(tag) .commit(); 

Una vez que vuelvas a pulsar, eliminará el fragmento B y mostrará el fragmento A con el mismo estado (antes de añadir el fragmento B )

Tenga en cuenta aquí tagFragmentA & tagFragmentB son etiquetas con las que se agregan fragmentos A y B respectivamente

  clearBackStackEntry(); rl.setVisibility(View.GONE); getSupportFragmentManager().beginTransaction() .replace(FRAGMENT_CONTAINER, new HomeScreen()) .addToBackStack(null).commit(); private void clearBackStackEntry() { int count = getSupportFragmentManager().getBackStackEntryCount(); if (count > 0) { getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); } } TRY THIS AND One more for fragment also try this: but use support.v4.app.Fragment, May be it will help you Fragment fr = new main(); android.support.v4.app.FragmentTransaction fragmentTransaction = getFragmentManager() .beginTransaction(); fragmentTransaction.replace(R.id.fragment_place, fr); fragmentTransaction.commit(); // getActivity().finish(); 

declarar

 setRetainInstance(true) 

En su fragmento onCreate (). Para recrear el estado anterior
Y el enlace será útil para comprender cómo funciona setRetainInstance.

Descripción de SetRetainInstance del fragmento (boolean)

¿Por qué utilizar Fragment # setRetainInstance (boolean)?

Gracias 🙂

Es muy sencillo manejar estas cosas. Puedo darle la muestra para manejar la copia de prensa en los agentes de Fr que hemos añadido.

He declarado una pila de fragmentos y empujo todos los fragmentos en ella como;

 public static Stack<Fragment> fragmentStack; 

Hacer un método como este:

  public static void replaceFragementsClick(Fragment fragementObj, Bundle bundleObj, String title){ try { FragmentManager fragmentManager = ((FragmentActivity) mContext).getSupportFragmentManager(); if (fragementObj != null) { fragementObj.setArguments(bundleObj); fragmentManager.beginTransaction().replace(R.id.frame_container, fragementObj).commit(); } DashBoardActivity.fragmentStack.push(fragementObj); } catch (Exception e) { e.printStackTrace(); } } 

Intente esto también:

  public static void replaceFragementsClickBack(Fragment fragementObj, Bundle bundleObj, String title){ try { FragmentManager fragmentManager = ((FragmentActivity) mContext).getSupportFragmentManager(); if (fragementObj != null) { fragementObj.setArguments(bundleObj); fragmentManager.beginTransaction().replace(R.id.frame_container, fragementObj).commit(); DashBoardActivity.fragmentStack.pop(); } } catch (Exception e) { e.printStackTrace(); } } 

En la actividad base en la que ha agregado, anule el valor de retroceso como:

 @Override public void onBackPressed() { /** * Do Current Fragment Pop * */ fragmentStack.pop(); if(fragmentStack.size() >0){ Bundle bunldeObj = new Bundle(); //******Exit from Current Fragment Fragment fragment = fragmentStack.pop(); // fragmentStack.push(fragment); if(fragment instanceof PhotosFragment){ bunldeObj.putString("position", "4"); replaceFragementsClick(fragment,bunldeObj,"Photos"); }else if(fragment instanceof PhotoDetatilFragment){ bunldeObj.putString("position", "4"); replaceFragementsClick(fragment,bunldeObj,"Photos"); }else if(fragment instanceof PhotoFullViewFragment){ bunldeObj.putString("position", "4"); replaceFragementsClick(fragment,bunldeObj,"Photos"); }else if(fragment instanceof HomeFragment){ bunldeObj.putString("position", "4"); replaceFragementsClick(fragment,bunldeObj,"Home"); }else if(fragment instanceof VideosFragment){ bunldeObj.putString("position", "4"); replaceFragementsClick(fragment,bunldeObj,"Videos"); }else if(fragment instanceof VideoDetailFragment){ bunldeObj.putString("position", "4"); replaceFragementsClick(fragment,bunldeObj,"Videos"); }else if(fragment instanceof VideoViewFragment){ bunldeObj.putString("position", "4"); replaceFragementsClick(fragment,bunldeObj,"Videos"); }else if(fragment instanceof MusicFragment){ bunldeObj.putString("position", "4"); replaceFragementsClick(fragment,bunldeObj,"Music"); }else if(fragment instanceof MusicListFragment){ bunldeObj.putString("position", "4"); replaceFragementsClick(fragment,bunldeObj,"Music"); }else if(fragment instanceof InstallAppsFragment){ bunldeObj.putString("position", "4"); replaceFragementsClick(fragment,bunldeObj,"Apps"); }else if(fragment instanceof MessageFragment){ bunldeObj.putString("position", "4"); replaceFragementsClick(fragment,bunldeObj,"Messages"); }else if(fragment instanceof MessageDetailFragment){ bunldeObj.putString("position", "4"); replaceFragementsClick(fragment,bunldeObj,"Messages"); }else if(fragment instanceof LocateDeviceFragment){ bunldeObj.putString("position", "4"); replaceFragementsClick(fragment,bunldeObj,"Locate Device"); }else if(fragment instanceof FilesFragmentBottomBar){ bunldeObj.putString("position", "4"); replaceFragementsClick(fragment,bunldeObj,"Files"); }else if(fragment instanceof AppsFragment){ bunldeObj.putString("position", "4"); replaceFragementsClick(fragment,bunldeObj,"Apps"); }else { super.onBackPressed(); Intent intent = new Intent(DashBoardActivity.this,ConnectDeviceActivity.class); startActivity(intent); finish(); } } 

No estoy claro el tipo de forma de vida que está utilizando para la implementación de las pestañas. Supuse de,

 ft.replace(android.R.id.tabcontent, fragment); 

Que podría haber implementado FragmentTabHost.

Escribe un customFragmentTabhost y anula

  @Override public void onTabChanged(String tabId) { FragmentTransaction t = getSupportFragmentManager().beginTransaction(); if (tabId.equals(“Tab1”)) { TabFragment1 fragment1 = null; if (getSupportFragmentManager().findFragmentByTag(“Tab1”) == null) { fragment1 = new TabFragment1(); } else { fragment1 = (TabFragment1) getSupportFragmentManager().findFragmentByTag("Tab1"); } t.replace(R.id.realContent, fragment1, "Tab1").addToBackStack(null).commit(); } } 

ACTUALIZAR:

  1. Asegúrese de que la actividad no se vuelva a crear en la orientación, si es así setRetainInstance (true), de modo que incluso si se recrea la actividad en el cambio de orientación, se conservarán los fragmentos.

  2. Da id para cualquier vista en el fragmento. Es importante que el sistema Android mantenga el estado.

  • Android ViewPager obtiene la vista actual
  • IllegalStateException: Fragmento ya agregado en el fragmento tabhost
  • Acceso mediante programación a una vista que se define en XML de un fragmento en Android
  • Cómo actualizar el contenido de la ficha de fragmento en el botón de clic
  • Android: cómo crear una aplicación de pestañas compleja con vistas
  • Cambiar el relleno de TextView en TabLayout
  • ¿Cómo utilizar el flash / led de la cámara como antorcha en una lengüeta de Samsung Galaxy?
  • Cambiar el índice de la pestaña de fragmentos con pestañas mediante programación
  • No se encontró ningún identificador de recurso para el atributo 'layout_behavior' en el paquete
  • Fragmento de Android encreateview llamado en el cambio de ficha
  • Android TabLayout ViewPager no inflar el fragmento de la pestaña en backstack
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.