Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Guardar estado de fragmento en ViewPager

He probado el código de ejemplo de la API y realmente no funcionó así que implementé mi propio:

FragmentPagerSupport

public class FragmentPagerSupport extends FragmentActivity { static final int NUM_ITEMS = 10; MyAdapter mAdapter; ViewPager mPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mAdapter = new MyAdapter(getSupportFragmentManager()); Log.i("Pager", "mAdapter = " + mAdapter.toString()); mPager = (ViewPager)findViewById(R.id.pager); if (mPager == null) Log.i("Pager", "mPager = null"); else Log.i("Pager", "mPager = " + mPager.toString()); Log.i("Pager", "Setting Pager Adapter"); mPager.setAdapter(mAdapter); } public static class MyAdapter extends FragmentPagerAdapter { public MyAdapter(FragmentManager fm) { super(fm); Log.i("Pager", "MyAdapter constructor"); } @Override public int getCount() { Log.i("Pager", "MyAdapter.getCount()"); return NUM_ITEMS; } @Override public Fragment getItem(int position) { Log.i("Pager", "MyAdapter.getItem()"); return TestFragment.newInstance(position); } } public static class TestFragment extends Fragment { public static TestFragment newInstance(int position) { Log.i("Pager", "TestFragment.newInstance()"); TestFragment fragment = new TestFragment(); Bundle args = new Bundle(); args.putInt("position", position); fragment.setArguments(args); return fragment; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub Log.i("Pager", "TestFragment.onCreateView()"); LinearLayout layout = (LinearLayout)inflater.inflate(R.layout.fragment_item, null); int position = getArguments().getInt("position"); TextView tv = (TextView)layout.findViewById(R.id.text); tv.setText("Fragment # " + position); tv.setTextColor(Color.WHITE); tv.setTextSize(30); return layout; } } 

}

Main.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> 

Fragment_item.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/text" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="@string/hello" /> </LinearLayout> 

Mi pregunta es, en lugar de crear una nueva instancia Fragment cada vez que el usuario desliza izquierda y derecha, ¿cómo puedo guardar el estado de un fragmento (en alguna estructura de datos) y luego restaurarlo?

La demostración API no parece tener ningún código de estado de ahorro de información en absoluto.

  • Eclipse no reconocerá el proyecto como biblioteca (ActionBarSherlock / ViewPagerIndicator)
  • Utilizar Pull to Refresh gridview en viewpager en Activity within ActivityGroup provoca ClassCastException
  • ViewPager FragmentPagerAdapter Nullpointer
  • Cómo alinear el centro de la pestaña activa en Android Disposición de la pestaña deslizante
  • IllegalStateException: No se puede cambiar la etiqueta del fragmento era android: switcher ahora android: switcher
  • Sincronizar dos ViewPagers con OnPageChangeListener
  • Control de dos ViewPager juntos
  • Reposición / margen de ViewPager de Android entre fragmentos de página
  • 6 Solutions collect form web for “Guardar estado de fragmento en ViewPager”

    Utilizar ViewPager.setOffscreenPageLimit() en FragmentActivity

     ViewPager pager = (ViewPager) findViewById(R.id.viewPager); pager.setOffscreenPageLimit(2); 

    Vea más en ¿Cómo le digo a mi FragmentPagerAdapter personalizado que deje de destruir mis fragmentos?

    Actualización: En el getItem de MyAdapter devuelve una nueva instancia de tu Fragmento. Android no llamará a getItem en cada golpe. Sólo llamará getItem para obtener una nueva instancia, pero reutilizará las instancias existentes siempre y cuando estén disponibles.

    Acerca de la parte del estado de la demostración. No puedo ayudarte. Creo que las técnicas normales para restaurar estado en Fragmentos / Actividades se aplican aquí, así que nada especial al cargarlo en un ViewPager (pero podría estar equivocado).

    Si anula

     public void destroyItem(View container, int position, Object object) 

    Sin llamar super, el fragmento no será destruido y será reutilizado.

    Sólo anule este método en FragmentpagerAdapter

     @Override public void destroyItem(ViewGroup container, int position, Object object) { // TODO Auto-generated method stub super.destroyItem(ViewGroup container, int position, Object object); } 

    Quitar super.destroyItem(ViewGroup container, int position, Object object);

    De su código

    El adaptador debe ser extendido de FragmentStatePagerAdapter en lugar de FragmentPageAdapter y el adaptador mantendrá la referencia de la posición al elemento del fragmento. En la actividad o el fragmento padre, set listener OnPageChangeListener para PageIndicator para detectar la posición del elemento de fragmento ha sido activado y actualizar el estado de los datos relacionados.

    Acerca del estado de los datos del elemento fragmento, creo que debería guardar / restaurar el estado de la actividad o Fragmento padre.

    El adaptador puede agregar algo de código como sigue:

     public static class MyAdapter extends FragmentStatePagerAdapter { private SparseArray<TestFragment> mPageReferenceMap = new SparseArray<TestFragment>(); ... @Override public Object instantiateItem(ViewGroup viewGroup, int position) { Object obj = super.instantiateItem(viewGroup, position); //Add the reference when fragment has been create or restore if (obj instanceof TestFragment) { TestFragment f= (TestFragment)obj; mPageReferenceMap.put(position, f); } return obj; } @Override public void destroyItem(ViewGroup container, int position, Object object) { //Remove the reference when destroy it mPageReferenceMap.remove(position); super.destroyItem(container, position, object); } public TestFragment getFragment(int key) { return mPageReferenceMap.get(key); } ... } 

    Espero que esto ayude.

    Tropecé en un terreno similar … Quería mantener mis fragmentos guardados en mi adaptador para evitar la recarga inútil ya que sólo tenía 5 fragmentos en el FragmentPagerAdapter .

    Básicamente tenía que crear una matriz y anular el getItem(position) :

     private StoryListFragment[] fragmentsArray = new StoryListFragment[getCount()]; public SectionsAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { if(fragmentsArray[position]!=null) return fragmentsArray[position]; StoryListFragment storyListFragment = null; switch(position){ case(0): storyListFragment = StoryListFragment.newInstance(StoriesBank.NEWS); break; case(1): storyListFragment = StoryListFragment.newInstance(StoriesBank.FEATURES); break; case(2): storyListFragment= StoryListFragment.newInstance(StoriesBank.ARTS); break; } fragmentsArray[position] = storyListFragment; return storyListFragment; } @Override public Object instantiateItem(ViewGroup container, int position) { StoryListFragment fragment = (StoryListFragment) super.instantiateItem(container, position); fragmentsArray[position] = fragment; return fragment; } 
    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.