Android oncreateview llamado dos veces

He visto esta pregunta hecha aquí más de una vez, pero no puedo averiguar cómo resolver mi caso.

Tengo una aplicación que el usuario hace esto:

1 – Abrir la barra de navegación y selecciona una opción (se crea un fragmento) (aquí estoy seleccionando la segunda opción);

public void selectItem(int position) { Fragment fragment = null; switch (position) { case FRAGMENT_OPTION1: ... break; case FRAGMENT_OPTION2: fragment = ControlPanelFragment.newInstance(); break; ... case FRAGMENT_OPTIONN: ... return; default: break; } if (fragment != null) { FragmentManager fragmentManager = getSupportFragmentManager(); fragmentManager.beginTransaction().replace(R.id.fragment_container, fragment).commitAllowingStateLoss(); } } 

2 – La opción seleccionada (ControlPanelFragment) se carga: 2.1 – El panel de control tiene pestañas y un iconpager. Para cada página de buscapersonas y para cada ficha se crea un nuevo fragmento. Tengo 3 pestañas y 3 páginas para crear 9 fragmentos;

 @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); if (savedInstanceState != null) { currentControlPanelOption = savedInstanceState.getInt("currentControlPanelOption", currentControlPanelOption); currentControlPanelTab = savedInstanceState.getInt("currentControlPanelTab", currentControlPanelTab); } setControlPanelTabs(); setIconPager(); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("currentControlPanelOption", pager.getCurrentItem()); outState.putInt("currentControlPanelTab", mTabHost.getCurrentTab()); } 

3 – En el setIconPager(); Tengo este código:

 pager = (ViewPager) view.findViewById(R.id.pager); cPanelPagerAdapter = new ControlPanelPagerAdapter(getChildFragmentManager()); pager.setOffscreenPageLimit(2); pager.setAdapter(cPanelPagerAdapter); 

donde ControlPanelPagerAdapter tiene este código:

 public Fragment getItem(int index) { Fragment fragment; switch (index) { case 1: fragment = FragmentA.newInstance(); break; case 2: fragment = FragmentB.newInstance(); break; case 3: fragment = FragmentC.newInstance(); break; default: fragment = null; break; } ... return fragment; } 

4 – FragmentA , FragmentB y FragmentC tienen casi el mismo código:

 public static FragmentA newInstance() { return new FragmentA(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_placeholder, container, false); return view; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); if (savedInstanceState == null) { fragmentA_Data = new FragmentADetail[3]; createTabInstance(0); } else { fragmentA_Data = (FragmentADetail[]) savedInstanceState.getSerializable("Data"); return; } } private void createTabInstance(int tab) { new FragmentADetail(); fragment = FragmentADetail.newInstance(tab); Bundle args = new Bundle(); args.putInt("tab", tab); fragment.setArguments(args); fragmentA_Data[tab] = fragment; FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction(); fragmentTransaction.replace(R.id.fragment_placeholder, fragmentA_Data[tab]); fragmentTransaction.commitAllowingStateLoss(); } public void getTabData(int tab) { if (fragmentA_Data[tab] == null) { createStoreTimePeriodInstance(tab); } else { if (fragmentA_Data[tab].getArguments() == null) { Bundle args = new Bundle(); args.putInt("tab", tab); fragmentA_Data[tab].setArguments(args); } FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction(); fragmentTransaction.replace(R.id.fragment_placeholder, fragmentA_Data[tab]); fragmentTransaction.commitAllowingStateLoss(); } } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putSerializable("data", fragmentA_Data); } 

5 – Finalmente, FragmentADetail tiene este código:

 public static FragmentADetail newInstance(int tab) { selectedTab = tab; return new FragmentADetail(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { view = inflater.inflate(R.layout.details_fragment, container, false); ... if (savedInstanceState != null) { selectedTab = savedInstanceState.getInt("selectedTab"); } ... } public void getTabData(int tab) { //This is where I'm getting the data that populates the layout } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("selectedTab", selectedTab); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); Bundle args = getArguments(); if (args != null) { getTabData(args.getInt("tab")); } } 

Ahora, imagina que estoy en FragmentA con la tercera pestaña seleccionada. Si giro la pantalla tengo esta secuencia de eventos:

  1. ControlPanelFragment onSaveInstanceState guarda la pestaña actual y el fragmento actual
  2. FragmentA onSaveInstanceState guarda los fragmentos de las pestañas para el paginador
  3. la segunda opción de navigationDrawer se vuelve a llamar fragment = ControlPanelFragment.newInstance();
  4. ControlPanelFragment onViewCreated se llama y puedo obtener la información de datos guardados y un nuevo buscapersonas y pestañas se crean
  5. FragmentA onViewCreated se llama y puedo extraer los datos guardados
  6. FragmentADetail onActivityCreated obtiene los datos guardados y carga los datos correctelly (al menos creo) Y a partir de ahora un segundo conjunto de métodos se llama la segunda vez y los datos que se guardó previamente se resetea y por lo que ahora muestra datos incorrectos
  7. ControlPanelFragment onSaveInstanceState pero ahora el savedInstanceState es nulo
  8. ControlPanelPagerAdapter getItem se denomina instanciar los 3 fragmentos
  9. FragmentA onSaveInstanceState su ahora llamado pero savedInstanceState es nulo
  10. FragmentADetail onActivityCreated se llama pero ahora la pestaña = 0

¿Puede alguien explicarme cómo puedo detener los pasos 7 a 10?

Me imagino cuál era mi problema.

Cuando estaba haciendo:

 case FRAGMENT_OPTION2: fragment = ControlPanelFragment.newInstance(); break; 

Estaba creando un fragmento y cuando rota la pantalla selectItem(int position) fue nuevamente llamado así que se creó una nueva instancia del mismo objeto así los pasos 7 y siguientes. La solución fue comprobar si el fragmento ya estaba creado y utilizarlo en lugar de crear uno nuevo. He guardado el fragmento inicial con una etiqueta y ellos buscaron esa etiqueta. Si la etiqueta existió, use ese fragmento de otra manera cree uno nuevo.

 public void selectItem(int position) { Fragment fragment = null; switch (position) { case FRAGMENT_OPTION1: ... break; case FRAGMENT_OPTION2: fragment = getSupportFragmentManager().findFragmentByTag(String.valueOf(position)); if (fragment == null) { fragment = ControlPanelFragment.newInstance(); } break; ... case FRAGMENT_OPTIONN: ... return; default: break; } if (fragment != null) { FragmentManager fragmentManager = getSupportFragmentManager(); fragmentManager.beginTransaction().replace(R.id.fragment_container, fragment, String.valueOf(position)).commitAllowingStateLoss(); } } 
  • Deshabilitar ItemTouchHelper para una parte de un visor
  • Barra de acción Sherlock: las pestañas no cambiarán en el paisaje al pasar
  • Android: ¿Cómo agregar iconos / drawables a la PagerTabStrip de la versión 4 de Android Support Lib?
  • ¿Animaciones de PageCurl en las transiciones de ViewPager?
  • ActionBar y ViewPager y CursorLoader funciona, pero tal vez hay mejor manera
  • Actualización dinámica de TabLayout sin cambiar la ficha seleccionada
  • Android Definir texto de TextView en fragmento que está en FragmentPagerAdapter
  • ¿Es posible acceder al Fragmento actual que está siendo visualizado por un ViewPager?
  • Android TabsAdapter con ActionbarSherlock
  • Funciones de llamada dentro de fragmentos en Android
  • ¿Cómo puedo mostrar un ViewPager en modo de pantalla completa?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.