La vista de fragmento en ViewPager no se restaura al reanudar

Tengo la configuración de ActionBar Tabs. Consta de 4 tabs. Todo está bien hasta que me alejo de TabbedFragment y regrese.

Creo tabs como esta:

  @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final ActionBar actionBar = getActionBar(); tabs = Lists.newArrayList(); tabs.add(new TabDefinition("Tab 1")); tabs.add(new TabDefinition("Tab 2")); tabs.add(new TabDefinition("Tab 3")); tabs.add(new TabDefinition("Tab 4")); for (TabDefinition tab : tabs) { actionBar.addTab(actionBar.newTab() .setText(tab.text) .setTag(tab.tag) .setTabListener(this)); } } 

Y inicialice el adaptador así:

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.paging_tab_container, container, false); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); viewPager = (ViewPager) view.findViewById(R.id.pager); viewPager.setAdapter(new FragmentStatePagerAdapter(getFragmentManager()) { @Override public Fragment getItem(int position) { return tabs.get(position).fragment; } @Override public int getCount() { return tabs.size(); } }); viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { @Override public void onPageSelected(int position) { getActionBar().setSelectedNavigationItem(position); } }); viewPager.setCurrentItem(getActionBar().getSelectedNavigationIndex(), true); } 

Al volver a TabbedFragment pestaña seleccionada y 1 al lado no tendría ningún contenido. Solo vista vacía Pero si selecciono el contenido actual del fragmento + 2, se carga. Y luego volviendo a ese primer fragmento, el contenido se vuelve a cargar.
Por ejemplo, tengo las tabs A, B, C, D. Antes de salir de TabbedFragment , había seleccionado la pestaña A. Al volver a TabbedFragment todavía estoy en la pestaña A, pero está vacía. También lo es la pestaña B.
Pero al seleccionar la pestaña C, se crea y se carga. Volviendo a la pestaña A, se recrea.

Cual podría ser el problema aquí?

Después de un tiempo se encontró con el mismo problema nuevamente, por lo que actualizó esta pregunta. Si está utilizando FragmentStatePagerAdapter , debe proporcionar FragmentManager través de getChildFragmentManager() lugar de getFragmentManager() . Consulte el problema 55068: ViewPager no actualiza los fragmentos secundarios cuando se realiza una navegación posterior mediante backstack.

Está bien, así que cuando uses un FragmentStatePagerAdapter tus fragmentos serán destruidos cuando offScreenPageLimit más de un fragmento de distancia, ya que de forma predeterminada, offScreenPageLimit está configurado en 1 por defecto, tal como se mencionó anteriormente.

Normalmente, esta clase se utiliza para una actividad que tiene un conjunto muy grande de Fragments , es decir, tiene que desplazarse por una gran cantidad de vistas. Si su aplicación no necesita más que 3 o 4 tabs, le sugiero usar FragmentPagerAdapter lugar, y luego especificar su offScreenPageLimit a algo así como 3, de modo que si llega a la 4ta pestaña, las 3 tabs anteriores aún estarán en la memoria.

Aquí hay un código de ejemplo para un proyecto en github que he creado que ilustra cómo cargar dinámicamente los fragmentos si no desea agregar este OffScreenPageLimit.

https://github.com/lt-tibs1984/InterfaceDemo/blob/master/src/com/divshark/interfacedemo/InterfaceDemoMain.java

Recorra todo este código en esta clase, y verá cómo estoy cargando dinámicamente los fragmentos, cada vez que se desliza mi ViewPager . Más notablemente en la parte inferior.

Puede descargar este código y usarlo como una base de prueba para lo que desea hacer. Intente agregar setOffScreenPageLimit (2) en el método onCreate () para viewPager y observe el comportamiento diferente. Para comprobar el comportamiento, edite el texto en el fragmento 1. Navegue Ausente y navegue hacia atrás, con este ajuste o no. Verás que cuando está configurado, el texto del fragmento sigue siendo lo que lo cambias, ya que el fragmento nunca se vuelve a crear.

Por favor proporcione preguntas adicionales si las tiene.

Buena suerte

ACTUALIZAR

 private static final String [] fragmentClasses = {"com.example.project.YourFragment1","com.example.project.YourFragment2","com.example.project.YourFragment3"}; viewPager.setAdapter(new FragmentStatePagerAdapter(getFragmentManager()) { @Override public Fragment getItem(int position) { Fragment fragmentAtPosition = null; // $$$$ This is the Important Part $$$$$ // Check to make sure that your array is not null, size is greater than 0 , current position is greater than equal to 0, and position is less than length if((fragmentClasses != null) && (fragmentClasses.length > 0)&&(position >= 0)&& (position < fragmentClasses.length)) { // Instantiate the Fragment at the current position of the Adapter fragmentAtPosition = Fragment.instantiate(getBaseContext(), fragmentClasses[position]); fragmentAtPosition.setRetainInstance(true); } return fragmentAtPosition; } @Override public int getCount() { return fragmentClasses.length; } }); 

El problema existe en los Fragmentos que usas como tabs, creo. Parece que no muestran nada cuando se reanudan (ver Fragmento ciclo de vida ). El problema “raro” de que solo la pestaña +/- 1 seleccionada actualmente esté vacía es porque el valor offScreenPageLimit de tu ViewPager es 1 por defecto. Todas las tabs por encima de este umbral se vuelven a crear.

Por lo tanto, al boost el valor, en su caso, todas las tabs aparecerán vacías después de reanudar. Verifique en su Código de fragmento qué métodos del ciclo de vida utiliza para inflar su diseño, establecer adaptadores, etc., porque eso es lo que está causando su problema.

Supongo que esto sucede porque al cargar el fragmento android carga el actual y el actual + 1, si depura, no vería que se llama a OnPause para el siguiente fragmento inmediato.

Puede volver a cargar el contenido mediante progtwigción en el métodoTabChanged () de TabHost.OnTabChangeListener.

Después de investigar mucho, esto funcionó para mí. Tengo un diseño complejo con 3 tabs en un fragmento, que se cambia para otros fragmentos. Me di cuenta de que ViewpagerAdapter mantendrá el estado, incluso si presiona el botón de inicio. Mi problema era cambiar hacia atrás y hacia adelante, anularía los elementos de vista de la IU del fragmento hijo y se bloquearía. La clave es no ViewPagerAdapter su ViewPagerAdapter . Agregar el cheque nulo para el adaptador funcionó para mí. Además, asegúrese de asignar setOffscreenPageLimit() para sus necesidades. Además, por lo que entiendo setRetainInstance(true); no debe usarse para fragmentos que tienen UI, está diseñado para fragmentos sin cabeza.

En el fragmento que contiene tus tabs:

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment_tab, container, false); tabLayout = (TabLayout) view.findViewById(R.id.tablayout); viewPager = (ViewPager) view.findViewById(R.id.viewPager); //Important!!! Do not fire the existing adapter!! if (viewPagerAdapter == null) { viewPagerAdapter = new ViewPagerAdapter(getChildFragmentManager()); viewPagerAdapter.addFragments(new AFragment(), "A"); viewPagerAdapter.addFragments(new BFragment(), "B"); viewPagerAdapter.addFragments(new CFragment(), "C"); } //Allocate retention buffers for three tabs, mandatory viewPager.setOffscreenPageLimit(3); tabLayout.setupWithViewPager(viewPager); viewPager.setAdapter(viewPagerAdapter); return view; } 

O más simplemente cuando navegue de regreso a tabbedfragment (suponiendo que usa un bash y el fragmento está dentro de una actividad) use:

 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 

Esto mantiene la actividad original y la mueve a la parte superior de la stack en lugar de volver a crearla, por lo que no es necesario volver a crear la viewPager.