with viewpager studio fragments example android android-fragments android-viewpager

viewpager - tabs android



Guardar estado de fragmento en ViewPager (6)

El adaptador debe extenderse desde FragmentStatePagerAdapter en lugar de FragmentPageAdapter y el adaptador mantendrá la referencia de posición a elemento de fragmento. En la actividad o fragmento principal, configure el detector OnPageChangeListener para PageIndicator para detectar la posición del elemento de fragmento que se ha activado y actualice el estado de los datos relacionados.

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

El adaptador puede agregar algunos códigos de la siguiente manera:

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.

Probé el código de muestra de la API y realmente no funcionó, así que implementé el mío:

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 de Fragment cada vez que el usuario pase de izquierda a derecha, ¿cómo guardo el estado de un fragmento (en cierta estructura de datos) y luego lo restauro?

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


Si anulas

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

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


Tropecé en un terreno similar ... Quería mantener mis fragmentos guardados en mi adaptador para evitar una recarga inútil, ya que solo tenía 5 fragmentos en FragmentPagerAdapter .

Básicamente tuve 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; }



simplemente 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); }

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

de tu código


Actualización: en el getItem de MyAdapter, devuelve una nueva instancia de su Fragment. Android no llamará a getItem en cada golpe. Solo llamará a getItem para obtener una nueva instancia, pero reutilizará las instancias existentes siempre que estén disponibles.

Acerca de la parte de estado de la demostración. No puedo ayudarte Creo que las técnicas normales para restaurar el estado en Fragements / Activities se aplican aquí, por lo que no es nada especial cuando se carga en un ViewPager (pero podría estar equivocado).