Quitar la página de fragmentos de ViewPager en Android

Estoy intentando agregar dinámicamente y quitar Fragments de un ViewPager, añadiendo trabajos sin ningún problema, pero la eliminación no trabaja como esperado.

Cada vez que quiera quitar el artículo actual, el último se quita.

También intenté usar un FragmentStatePagerAdapter o devolver POSITION_NONE en el método getItemPosition del adaptador.

¿Qué estoy haciendo mal?

He aquí un ejemplo básico:

MainActivity.java

public class MainActivity extends FragmentActivity implements TextProvider { private Button mAdd; private Button mRemove; private ViewPager mPager; private MyPagerAdapter mAdapter; private ArrayList<String> mEntries = new ArrayList<String>(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mEntries.add("pos 1"); mEntries.add("pos 2"); mEntries.add("pos 3"); mEntries.add("pos 4"); mEntries.add("pos 5"); mAdd = (Button) findViewById(R.id.add); mRemove = (Button) findViewById(R.id.remove); mPager = (ViewPager) findViewById(R.id.pager); mAdd.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { addNewItem(); } }); mRemove.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { removeCurrentItem(); } }); mAdapter = new MyPagerAdapter(this.getSupportFragmentManager(), this); mPager.setAdapter(mAdapter); } private void addNewItem() { mEntries.add("new item"); mAdapter.notifyDataSetChanged(); } private void removeCurrentItem() { int position = mPager.getCurrentItem(); mEntries.remove(position); mAdapter.notifyDataSetChanged(); } @Override public String getTextForPosition(int position) { return mEntries.get(position); } @Override public int getCount() { return mEntries.size(); } private class MyPagerAdapter extends FragmentPagerAdapter { private TextProvider mProvider; public MyPagerAdapter(FragmentManager fm, TextProvider provider) { super(fm); this.mProvider = provider; } @Override public Fragment getItem(int position) { return MyFragment.newInstance(mProvider.getTextForPosition(position)); } @Override public int getCount() { return mProvider.getCount(); } } } 

TextProvider.java

 public interface TextProvider { public String getTextForPosition(int position); public int getCount(); } 

MyFragment.java

 public class MyFragment extends Fragment { private String mText; public static MyFragment newInstance(String text) { MyFragment f = new MyFragment(text); return f; } public MyFragment() { } public MyFragment(String text) { this.mText = text; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment, container, false); ((TextView) root.findViewById(R.id.position)).setText(mText); return root; } } 

Activity_main.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/add" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="add new item" /> <Button android:id="@+id/remove" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="remove current item" /> <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="0dip" android:layout_weight="1" /> </LinearLayout> 

Fragmento.xml

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

10 Solutions collect form web for “Quitar la página de fragmentos de ViewPager en Android”

La solución de Louth no fue suficiente para que las cosas funcionaran para mí, ya que los fragmentos existentes no se estaban destruyendo. Motivado por esta respuesta , encontré que la solución es anular el getItemId(int position) de FragmentPagerAdapter para dar un nuevo identificador único siempre que haya habido un cambio en la posición esperada de un Fragmento.

Código fuente:

 private class MyPagerAdapter extends FragmentPagerAdapter { private TextProvider mProvider; private long baseId = 0; public MyPagerAdapter(FragmentManager fm, TextProvider provider) { super(fm); this.mProvider = provider; } @Override public Fragment getItem(int position) { return MyFragment.newInstance(mProvider.getTextForPosition(position)); } @Override public int getCount() { return mProvider.getCount(); } //this is called when notifyDataSetChanged() is called @Override public int getItemPosition(Object object) { // refresh all fragments when data set changed return PagerAdapter.POSITION_NONE; } @Override public long getItemId(int position) { // give an ID different from position when position has been changed return baseId + position; } /** * Notify that the position of a fragment has been changed. * Create a new ID for each position to force recreation of the fragment * @param n number of items which have been changed */ public void notifyChangeInPosition(int n) { // shift the ID returned by getItemId outside the range of all previous fragments baseId += getCount() + n; } } 

Ahora, por ejemplo, si elimina una sola pestaña o efectúa algún cambio en el orden, debe llamar a notifyChangeInPosition(1) antes de llamar a notifyDataSetChanged() , lo que asegurará que todos los fragmentos se recrearán.

Por qué esta solución funciona

Sobreescribir getItemPosition ():

Cuando se llama notifyDataSetChanged() , el adaptador llama al método notifyChanged() del ViewPager que está conectado. ViewPager comprueba el valor devuelto por getItemPosition() del adaptador para cada elemento, eliminando los elementos que devuelven POSITION_NONE (consulte el código fuente ) y luego vuelven a getItemPosition() .

Sobreescribir getItemId ():

Esto es necesario para evitar que el adaptador ViewPager el fragmento antiguo cuando el ViewPager está repoblando. Usted puede entender fácilmente por qué esto funciona mirando el código fuente de instantiateItem () en FragmentPagerAdapter .

  final long itemId = getItemId(position); // Do we already have this fragment? String name = makeFragmentName(container.getId(), itemId); Fragment fragment = mFragmentManager.findFragmentByTag(name); if (fragment != null) { if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment); mCurTransaction.attach(fragment); } else { fragment = getItem(position); if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment); mCurTransaction.add(container.getId(), fragment, makeFragmentName(container.getId(), itemId)); } 

Como se puede ver, el método getItem() sólo se llama si el gestor de fragmentos no encuentra fragmentos existentes con la misma Id. A mí me parece un error que los viejos fragmentos todavía están conectados incluso después de que notifyDataSetChanged() se llame, pero la documentación para ViewPager indica claramente que:

Tenga en cuenta que esta clase está actualmente bajo diseño y desarrollo temprano. Es probable que la API cambie en las actualizaciones posteriores de la biblioteca de compatibilidad, lo que requiere cambios en el código fuente de las aplicaciones cuando se compilan con la versión más reciente.

Así que espero que la solución dada aquí no será necesaria en una futura versión de la biblioteca de soporte.

ViewPager no quita los fragmentos con el código anterior porque carga varias vistas (o fragmentos en su caso) en la memoria. Además de la vista visible, también carga la vista a ambos lados de la visible. Esto proporciona el desplazamiento suave de la vista a la vista que hace que el ViewPager sea tan genial.

Para lograr el efecto que desea, necesita hacer un par de cosas.

  1. Cambie el FragmentPagerAdapter a un FragmentStatePagerAdapter. La razón de esto es que el FragmentPagerAdapter mantendrá siempre todas las vistas que carga en la memoria. Donde el FragmentStatePagerAdapter dispone de vistas que quedan fuera de las vistas actuales y viables.

  2. Substituya el método del adaptador getItemPosition (mostrado abajo). Cuando llamamos mAdapter.notifyDataSetChanged(); ViewPager interroga al adaptador para determinar qué ha cambiado en términos de posicionamiento. Utilizamos este método para decir que todo ha cambiado para reprocesar todo su posicionamiento en la vista.

Y aquí está el código …

 private class MyPagerAdapter extends FragmentStatePagerAdapter { //... your existing code @Override public int getItemPosition(Object object){ return PagerAdapter.POSITION_NONE; } } 

Mi solución de trabajo para eliminar la página de fragmentos de paginador de vista

 public class MyFragmentAdapter extends FragmentStatePagerAdapter { private ArrayList<ItemFragment> pages; public MyFragmentAdapter(FragmentManager fragmentManager, ArrayList<ItemFragment> pages) { super(fragmentManager); this.pages = pages; } @Override public Fragment getItem(int index) { return pages.get(index); } @Override public int getCount() { return pages.size(); } @Override public int getItemPosition(Object object) { int index = pages.indexOf (object); if (index == -1) return POSITION_NONE; else return index; } } 

Y cuando necesito quitar una página por índice hago esto

 pages.remove(position); // ArrayList<ItemFragment> adapter.notifyDataSetChanged(); // MyFragmentAdapter 

Aquí está mi inicialización del adaptador

 MyFragmentAdapter adapter = new MyFragmentAdapter(getSupportFragmentManager(), pages); viewPager.setAdapter(adapter); 

Usted puede combinar ambos para mejor:

 private class MyPagerAdapter extends FragmentStatePagerAdapter { //... your existing code @Override public int getItemPosition(Object object){ if(Any_Reason_You_WantTo_Update_Positions) //this includes deleting or adding pages return PagerAdapter.POSITION_NONE; } else return PagerAdapter.POSITION_UNCHANGED; //this ensures high performance in other operations such as editing list items. } 

Tuve la idea de simplemente copiar el código fuente de android.support.v4.app.FragmentPagerAdpater en una clase personalizada llamada CustumFragmentPagerAdapter . Esto me dio la oportunidad de modificar el instantiateItem(...) para que cada vez que se llama, elimina / destruye el fragmento actualmente conectado antes de añadir el nuevo fragmento recibido del método getItem() .

Simplemente modifique el instantiateItem(...) de la siguiente manera:

 @Override public Object instantiateItem(ViewGroup container, int position) { if (mCurTransaction == null) { mCurTransaction = mFragmentManager.beginTransaction(); } final long itemId = getItemId(position); // Do we already have this fragment? String name = makeFragmentName(container.getId(), itemId); Fragment fragment = mFragmentManager.findFragmentByTag(name); // remove / destroy current fragment if (fragment != null) { mCurTransaction.remove(fragment); } // get new fragment and add it fragment = getItem(position); mCurTransaction.add(container.getId(), fragment, makeFragmentName(container.getId(), itemId)); if (fragment != mCurrentPrimaryItem) { fragment.setMenuVisibility(false); fragment.setUserVisibleHint(false); } return fragment; } 

Mi código de versión final, todos los errores fijados. Me tomó 3 días

https://github.com/lin1987www/FragmentBuilder/blob/master/app/src/main/java/android/support/v4/app/FragmentStatePagerAdapterFix.java

 public class FragmentStatePagerAdapterFix extends PagerAdapter { private static final String TAG = FragmentStatePagerAdapterFix.class.getSimpleName(); private static final boolean DEBUG = false; private WeakReference<FragmentActivity> wrFragmentActivity; private WeakReference<Fragment> wrParentFragment; private final FragmentManager mFragmentManager; private FragmentTransaction mCurTransaction = null; protected ArrayList<Fragment> mFragments = new ArrayList<>(); protected ArrayList<FragmentState> mFragmentStates = new ArrayList<>(); protected ArrayList<String> mFragmentTags = new ArrayList<>(); protected ArrayList<String> mFragmentClassNames = new ArrayList<>(); protected ArrayList<Bundle> mFragmentArgs = new ArrayList<>(); private Fragment mCurrentPrimaryItem = null; private boolean[] mTempPositionChange; @Override public int getCount() { return mFragmentClassNames.size(); } public FragmentActivity getFragmentActivity() { return wrFragmentActivity.get(); } public Fragment getParentFragment() { return wrParentFragment.get(); } public FragmentStatePagerAdapterFix(FragmentActivity activity) { mFragmentManager = activity.getSupportFragmentManager(); wrFragmentActivity = new WeakReference<>(activity); wrParentFragment = new WeakReference<>(null); } public FragmentStatePagerAdapterFix(Fragment fragment) { mFragmentManager = fragment.getChildFragmentManager(); wrFragmentActivity = new WeakReference<>(fragment.getActivity()); wrParentFragment = new WeakReference<>(fragment); } public void add(Class<? extends android.support.v4.app.Fragment> fragClass) { add(fragClass, null, null); } public void add(Class<? extends android.support.v4.app.Fragment> fragClass, Bundle args) { add(fragClass, args, null); } public void add(Class<? extends android.support.v4.app.Fragment> fragClass, String tag) { add(fragClass, null, tag); } public void add(Class<? extends android.support.v4.app.Fragment> fragClass, Bundle args, String tag) { add(fragClass, args, tag, getCount()); } public void add(Class<? extends android.support.v4.app.Fragment> fragClass, Bundle args, String tag, int position) { mFragments.add(position, null); mFragmentStates.add(position, null); mFragmentTags.add(position, tag); mFragmentClassNames.add(position, fragClass.getName()); mFragmentArgs.add(position, args); mTempPositionChange = new boolean[getCount()]; } public void remove(int position) { if (position < getCount()) { mTempPositionChange = new boolean[getCount()]; for (int i = position; i < mTempPositionChange.length; i++) { mTempPositionChange[i] = true; } mFragments.remove(position); mFragmentStates.remove(position); mFragmentTags.remove(position); mFragmentClassNames.remove(position); mFragmentArgs.remove(position); } } public void clear(){ mFragments.clear(); mFragmentStates.clear(); mFragmentTags.clear(); mFragmentClassNames.clear(); mFragmentArgs.clear(); } @Override public void startUpdate(ViewGroup container) { } @Override public Object instantiateItem(ViewGroup container, int position) { Fragment fragment; // If we already have this item instantiated, there is nothing // to do. This can happen when we are restoring the entire pager // from its saved state, where the fragment manager has already // taken care of restoring the fragments we previously had instantiated. fragment = mFragments.get(position); if (fragment != null) { return fragment; } if (mCurTransaction == null) { mCurTransaction = mFragmentManager.beginTransaction(); } FragmentState fs = mFragmentStates.get(position); if (fs != null) { fragment = fs.instantiate(getFragmentActivity(), getParentFragment()); // Fix bug // http://stackoverflow.com/questions/11381470/classnotfoundexception-when-unmarshalling-android-support-v4-view-viewpagersav if (fragment.mSavedFragmentState != null) { fragment.mSavedFragmentState.setClassLoader(fragment.getClass().getClassLoader()); } } if (fragment == null) { fragment = Fragment.instantiate(getFragmentActivity(), mFragmentClassNames.get(position), mFragmentArgs.get(position)); } if (DEBUG) { Log.v(TAG, "Adding item #" + position + ": f=" + fragment); } fragment.setMenuVisibility(false); fragment.setUserVisibleHint(false); mFragments.set(position, fragment); mFragmentStates.set(position, null); mCurTransaction.add(container.getId(), fragment, mFragmentTags.get(position)); return fragment; } @Override public void destroyItem(ViewGroup container, int position, Object object) { Fragment fragment = (Fragment) object; if (mCurTransaction == null) { mCurTransaction = mFragmentManager.beginTransaction(); } if (DEBUG) { Log.v(TAG, "Removing item #" + position + ": f=" + object + " v=" + ((Fragment) object).getView()); } if (position < getCount()) { FragmentState fragmentState = new FragmentState(fragment); Fragment.SavedState savedState = mFragmentManager.saveFragmentInstanceState(fragment); if (savedState != null) { fragmentState.mSavedFragmentState = savedState.mState; } mFragmentStates.set(position, fragmentState); mFragments.set(position, null); } mCurTransaction.remove(fragment); } @Override public void setPrimaryItem(ViewGroup container, int position, Object object) { Fragment fragment = (Fragment) object; if (fragment != mCurrentPrimaryItem) { if (mCurrentPrimaryItem != null) { mCurrentPrimaryItem.setMenuVisibility(false); mCurrentPrimaryItem.setUserVisibleHint(false); } if (fragment != null) { fragment.setMenuVisibility(true); fragment.setUserVisibleHint(true); } mCurrentPrimaryItem = fragment; } } @Override public void finishUpdate(ViewGroup container) { if (mCurTransaction != null) { mCurTransaction.commitAllowingStateLoss(); mCurTransaction = null; mFragmentManager.executePendingTransactions(); // Fix: Fragment is added by transaction. BUT didn't add to FragmentManager's mActive. for (Fragment fragment : mFragments) { if (fragment != null) { fixActiveFragment(mFragmentManager, fragment); } } } } @Override public boolean isViewFromObject(View view, Object object) { return ((Fragment) object).getView() == view; } @Override public Parcelable saveState() { Bundle state = null; // 目前顯示的 Fragments for (int i = 0; i < mFragments.size(); i++) { Fragment f = mFragments.get(i); if (f != null && f.isAdded()) { if (state == null) { state = new Bundle(); } String key = "f" + i; mFragmentManager.putFragment(state, key, f); } } if (mFragmentStates.size() > 0) { if (state == null) { state = new Bundle(); } FragmentState[] fs = new FragmentState[mFragmentStates.size()]; mFragmentStates.toArray(fs); state.putParcelableArray("states_fragment", fs); } return state; } @Override public void restoreState(Parcelable state, ClassLoader loader) { if (state != null) { Bundle bundle = (Bundle) state; bundle.setClassLoader(loader); Parcelable[] fs = bundle.getParcelableArray("states_fragment"); mFragments.clear(); mFragmentStates.clear(); mFragmentTags.clear(); mFragmentClassNames.clear(); mFragmentArgs.clear(); if (fs != null) { for (int i = 0; i < fs.length; i++) { FragmentState fragmentState = (FragmentState) fs[i]; mFragmentStates.add(fragmentState); if (fragmentState != null) { mFragmentArgs.add(fragmentState.mArguments); mFragmentTags.add(fragmentState.mTag); mFragmentClassNames.add(fragmentState.mClassName); } else { mFragmentArgs.add(null); mFragmentTags.add(null); mFragmentClassNames.add(null); } mFragments.add(null); } } Iterable<String> keys = bundle.keySet(); for (String key : keys) { if (key.startsWith("f")) { int index = Integer.parseInt(key.substring(1)); Fragment f = mFragmentManager.getFragment(bundle, key); if (f != null) { f.setMenuVisibility(false); mFragments.set(index, f); mFragmentArgs.set(index, f.mArguments); mFragmentTags.set(index, f.mTag); mFragmentClassNames.set(index, f.getClass().getName()); } else { Log.w(TAG, "Bad fragment at key " + key); } } } // If restore will change notifyDataSetChanged(); } } public static void fixActiveFragment(FragmentManager fragmentManager, Fragment fragment) { FragmentManagerImpl fm = (FragmentManagerImpl) fragmentManager; if (fm.mActive != null) { int index = fragment.mIndex; Fragment origin = fm.mActive.get(index); if (origin != null) { if ((origin.mIndex != fragment.mIndex) || !(origin.equals(fragment))) { Log.e(TAG, String.format("fixActiveFragment: Not Equal! Origin: %s %s, Fragment: %s $s", origin.getClass().getName(), origin.mIndex, fragment.getClass().getName(), fragment.mIndex )); } } fm.mActive.set(index, fragment); } } // Fix // http://stackoverflow.com/questions/10396321/remove-fragment-page-from-viewpager-in-android @Override public int getItemPosition(Object object) { int index = mFragments.indexOf(object); if (index < 0) { return PagerAdapter.POSITION_NONE; } boolean isPositionChange = mTempPositionChange[index]; int result = PagerAdapter.POSITION_UNCHANGED; if (isPositionChange) { result = PagerAdapter.POSITION_NONE; } return result; } } 

La respuesta de Louth funciona bien. Pero no creo que siempre regrese POSITION_NONE es una buena idea. Porque POSITION_NONE significa que el fragmento debe ser destruido y se creará un nuevo fragmento. Puede comprobar que en la función dataSetChanged en el código fuente de ViewPager.

  if (newPos == PagerAdapter.POSITION_NONE) { mItems.remove(i); i--; ... not related code mAdapter.destroyItem(this, ii.position, ii.object); 

Así que creo que es mejor que uses un arraylist de weakReference para guardar todos los fragmentos que has creado. Y cuando agregas o quitas alguna página, puedes obtener la posición correcta de tu propio arraylist.

  public int getItemPosition(Object object) { for (int i = 0; i < mFragmentsReferences.size(); i ++) { WeakReference<Fragment> reference = mFragmentsReferences.get(i); if (reference != null && reference.get() != null) { Fragment fragment = reference.get(); if (fragment == object) { return i; } } } return POSITION_NONE; } 

Según los comentarios, getItemPosition se llama cuando la vista de host está intentando determinar si la posición de un elemento ha cambiado. Y el valor de retorno significa su nueva posición.

Pero esto no es suficiente. Todavía tenemos un paso importante que tomar. En el código fuente de FragmentStatePagerAdapter, existe una matriz denominada "mFragments" que almacena en caché los fragmentos que no se destruyen. Y en la función instantiateItem.

 if (mFragments.size() > position) { Fragment f = mFragments.get(position); if (f != null) { return f; } } 

Devolvió el fragmento en caché directamente cuando se encuentra que el fragmento en caché no es nulo. Así que hay un problema. De ejemplo, vamos a eliminar una página en la posición 2, En primer lugar, Eliminar ese fragmento de nuestra propia referencia arraylist. Así que en getItemPosition devolverá POSITION_NONE para ese fragmento, y entonces ese fragmento será destruido y eliminado de "mFragments".

  mFragments.set(position, null); 

Ahora el fragmento en la posición 3 estará en la posición 2. E instantiatedItem con la posición param 3 será llamado. En este momento, el tercer elemento en "mFramgents" no es nulo, por lo que volverá directamente. Pero en realidad lo que devolvió es el fragmento en la posición 2. Así que cuando nos volvemos a la página 3, encontraremos una página vacía allí.

Para evitar este problema. Mi consejo es que usted puede copiar el código fuente de FragmentStatePagerAdapter en su propio proyecto, y cuando usted agrega o quita operaciones, usted debe agregar y quitar elementos en el arraylist del "mFragments".

Las cosas serán más simples si solo usa PagerAdapter en lugar de FragmentStatePagerAdapter. Buena suerte.

Agregar o quitar fragmento en viewpager dinámicamente.
Llame a setupViewPager (viewPager) al iniciar la actividad. Para cargar el fragmento diferente llamar setupViewPagerCustom (viewPager). Por ejemplo, en el botón de llamada de clic: setupViewPagerCustom (viewPager);

  private void setupViewPager(ViewPager viewPager) { ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager()); adapter.addFrag(new fragmnet1(), "HOME"); adapter.addFrag(new fragmnet2(), "SERVICES"); viewPager.setAdapter(adapter); } private void setupViewPagerCustom(ViewPager viewPager) { ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager()); adapter.addFrag(new fragmnet3(), "Contact us"); adapter.addFrag(new fragmnet4(), "ABOUT US"); viewPager.setAdapter(adapter); } //Viewpageradapter, handles the views static class ViewPagerAdapter extends FragmentStatePagerAdapter { private final List<Fragment> mFragmentList = new ArrayList<>(); private final List<String> mFragmentTitleList = new ArrayList<>(); public ViewPagerAdapter(FragmentManager manager){ super(manager); } @Override public Fragment getItem(int position) { return mFragmentList.get(position); } @Override public int getCount() { return mFragmentList.size(); } @Override public int getItemPosition(Object object){ return PagerAdapter.POSITION_NONE; } public void addFrag(Fragment fragment, String title){ mFragmentList.add(fragment); mFragmentTitleList.add(title); } @Override public CharSequence getPageTitle(int position){ return mFragmentTitleList.get(position); } } 

Tuve algunos problemas con FragmentStatePagerAdapter . Después de quitar un artículo:

  • Había otro artículo usado para una posición (un artículo que no pertenecía a la posición pero a una posición al lado de ella)
  • O algún fragmento no fue cargado (sólo había fondo en blanco visible en esa página)

Después de muchos experimentos, hice la siguiente solución.

 public class SomeAdapter extends FragmentStatePagerAdapter { private List<Item> items = new ArrayList<Item>(); private boolean removing; @Override public Fragment getItem(int position) { ItemFragment fragment = new ItemFragment(); Bundle args = new Bundle(); // use items.get(position) to configure fragment fragment.setArguments(args); return fragment; } @Override public int getCount() { return items.size(); } @Override public int getItemPosition(Object object) { if (removing) { return PagerAdapter.POSITION_NONE; } Item item = getItemOfFragment(object); int index = items.indexOf(item); if (index == -1) { return POSITION_NONE; } else { return index; } } public void addItem(Item item) { items.add(item); notifyDataSetChanged(); } public void removeItem(int position) { items.remove(position); removing = true; notifyDataSetChanged(); removing = false; } } 

Esta solución sólo utiliza un hack en caso de quitar un elemento. De lo contrario (por ejemplo, al agregar un elemento) conserva la limpieza y el rendimiento de un código original.

Por supuesto, desde el exterior del adaptador, se llama sólo addItem / removeItem, no es necesario llamar a notifyDataSetChanged ().

Espero que esto pueda ayudar a lo que quieras.

 private class MyPagerAdapter extends FragmentStatePagerAdapter { //... your existing code @Override public int getItemPosition(Object object){ return PagerAdapter.POSITION_UNCHANGED; } } 
  • ViewPager con FragmentPagerAdapter no se muestra
  • Haga clic en la pestaña de Android
  • FragmentPagerAdapter Deslizar para mostrar ListView 1/3 Anchura de la pantalla
  • ¿Cómo uso FragmentPagerAdapter para tener pestañas con contenido diferente?
  • Diferencia entre FragmentPagerAdapter y FragmentStatePagerAdapter
  • Cómo reemplazar Fragment dentro de ViewPager, usando PagerAdapter?
  • ViewPager dentro de fragmento, cómo conservar el estado?
  • FragmentPagerAdapter con ViewPager y dos Fragmentos. Ir a la primera de la segunda y actualizar el primer texto
  • ViewPager + FragmentPagerAdapter dentro de un DialogFragment obtiene "IllegalArgumentException: No se encontró ninguna vista ..."
  • Eliminar Elemento + Desplazarse a Siguiente en Android ViewPager
  • Cambia dinámicamente el título de un android.support.v4.view.PagerTitleStrip
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.