Eliminar Fragment Page de ViewPager en Android

Estoy intentando agregar y eliminar dinámicamente Fragmentos de un ViewPager, agregando trabajos sin ningún problema, pero eliminar no funciona como se esperaba.

Cada vez que quiero eliminar el elemento actual, el último se elimina.

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

¿Qué estoy haciendo mal?

Aquí hay 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 mEntries = new ArrayList(); @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

   

fragment.xml

     

La solución de Louth no fue suficiente para que las cosas funcionasen para mí, ya que los fragmentos existentes no se destruían. Motivado por esta respuesta , encontré que la solución es anular el getItemId(int position) de FragmentPagerAdapter para dar una nueva identificación única siempre que haya habido un cambio en la posición esperada de un Fragment.

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 realiza algún cambio en el pedido, debe llamar a notifyChangeInPosition(1) antes de llamar a notifyDataSetChanged() , lo que garantizará que todos los Fragmentos se volverán a crear.

Por qué esta solución funciona

Anulación de getItemPosition ():

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

Anulando getItemId ():

Esto es necesario para evitar que el adaptador ViewPager a cargar el fragmento anterior cuando ViewPager esté ViewPager . Puedes entender fácilmente por qué funciona al mirar el código fuente de instanciateItem () 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 puede ver, el método getItem() solo se getItem() si el administrador de fragmentos no encuentra fragmentos existentes con el mismo Id. Para mí, parece un error que los fragmentos antiguos todavía estén adjuntos incluso después de notifyDataSetChanged() , pero la documentación de ViewPager claramente que:

Tenga en cuenta que esta clase se encuentra actualmente en fase inicial de diseño y desarrollo. La API probablemente cambie en las actualizaciones posteriores de la biblioteca de compatibilidad, lo que requerirá cambios en el código fuente de las aplicaciones cuando se compilen con la versión más nueva.

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

ViewPager no elimina 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 cada lado del visible. Esto proporciona un desplazamiento suave desde la vista hacia la vista que hace que ViewPager sea tan genial.

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

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

  2. Reemplace el método del adaptador getItemPosition (que se muestra a continuación). Cuando llamamos a mAdapter.notifyDataSetChanged(); el ViewPager interroga al adaptador para determinar qué ha cambiado en términos de posicionamiento. Usamos este método para decir que todo ha cambiado, así que reprocesar todo el posicionamiento de su 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 fragmento del buscapersonas

 public class MyFragmentAdapter extends FragmentStatePagerAdapter { private ArrayList pages; public MyFragmentAdapter(FragmentManager fragmentManager, ArrayList 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 eliminar algunas páginas por índice, hago esto

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

Aquí está la inicialización de mi adaptador

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

El fragmento ya debe estar eliminado, pero el problema era el estado de salvar del viewpager

Tratar

 myViewPager.setSaveFromParentEnabled(false); 

¡Nada funcionó, pero esto resolvió el problema!

¡Salud!

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 elemento instantiateItem(...) para que cada vez que se getItem() , elimine / destruya el fragmento adjunto actualmente antes de agregar el nuevo fragmento recibido del método getItem() .

Simplemente modifique el elemento 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; } 

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. } 

Mi código de versión final, solucionó TODOS los errores. 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 wrFragmentActivity; private WeakReference wrParentFragment; private final FragmentManager mFragmentManager; private FragmentTransaction mCurTransaction = null; protected ArrayList mFragments = new ArrayList<>(); protected ArrayList mFragmentStates = new ArrayList<>(); protected ArrayList mFragmentTags = new ArrayList<>(); protected ArrayList mFragmentClassNames = new ArrayList<>(); protected ArrayList 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 fragClass) { add(fragClass, null, null); } public void add(Class fragClass, Bundle args) { add(fragClass, args, null); } public void add(Class fragClass, String tag) { add(fragClass, null, tag); } public void add(Class fragClass, Bundle args, String tag) { add(fragClass, args, tag, getCount()); } public void add(Class 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 restreState(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 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 restre 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 se debe destruir y se creará un nuevo fragmento. Puede verificarlo 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 será mejor que utilices una lista de arrays de weakReference para guardar todos los fragmentos que hayas creado. Y cuando agrega o elimina alguna página, puede obtener la posición correcta desde su propia lista de arrays.

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

De acuerdo con los comentarios, getItemPosition se invoca cuando la vista de host intenta 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 a seguir. En el código fuente de FragmentStatePagerAdapter, hay una matriz llamada “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 almacenado en caché directamente cuando descubre que el fragmento almacenado en caché no es nulo. Entonces hay un problema De ejemplo, eliminemos una página en la posición 2, En primer lugar, eliminamos ese fragmento de nuestra propia lista de arrays de referencia. entonces en getItemPosition devolverá POSITION_NONE para ese fragmento, y luego 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. Y se llamará al elemento instanciado con la posición param 3. En este momento, el tercer elemento en “mFramgents” no es nulo, por lo que regresará directamente. Pero en realidad, lo que devuelve es el fragmento en la posición 2. Entonces, cuando pasemos a la página 3, encontraremos una página vacía allí.

Para evitar este problema Mi consejo es que puede copiar el código fuente de FragmentStatePagerAdapter en su propio proyecto, y cuando agrega o elimina operaciones, debe agregar y eliminar elementos en la lista de selección “mFragments”.

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

agregue o elimine el fragmento en el viewpager dinámicamente.
Llame a setupViewPager (viewPager) en el inicio de la actividad. Para cargar diferentes fragmentos, llame a setupViewPagerCustom (viewPager). por ejemplo, al hacer clic en el botón llamar: 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 mFragmentList = new ArrayList<>(); private final List 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 eliminar un artículo:

  • había otro elemento utilizado para un puesto (un elemento que no pertenecía al puesto sino a un puesto al lado)
  • o algún fragmento no se cargó (solo había fondo en blanco visible en esa página)

Después de muchos experimentos, se me ocurrió la siguiente solución.

 public class SomeAdapter extends FragmentStatePagerAdapter { private List items = new ArrayList(); 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 solo utiliza un hack en caso de eliminar un elemento. De lo contrario (por ejemplo, al agregar un artículo) conserva la limpieza y el rendimiento de un código original.

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

Prueba esta solución He utilizado enlace de datos para la vista de enlace. Puede usar la función común “findViewById ()”.

 public class ActCPExpense extends BaseActivity implements View.OnClickListener, { private static final String TAG = ActCPExpense.class.getSimpleName(); private Context mContext; private ActCpLossBinding mBinding; private ViewPagerAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); try { setContentView(R.layout.act_cp_loss); mBinding = DataBindingUtil.setContentView(this, R.layout.act_cp_loss); mContext = ActCPExpense.this; initViewsAct(); } catch (Exception e) { LogUtils.LOGE(TAG, e); } } private void initViewsAct() { adapter = new ViewPagerAdapter(getSupportFragmentManager()); adapter.addFragment(FragmentCPPayee.newInstance(), "Title"); mBinding.viewpager.setAdapter(adapter); mBinding.tab.setViewPager(mBinding.viewpager); } @Override public boolean onOptionsItemSelected(MenuItem itemActUtility) { int i = itemActUtility.getItemId(); if (i == android.R.id.home) { onBackPressed(); } return super.onOptionsItemSelected(itemActUtility); } @Override public void onClick(View view) { super.onClick(view); int id = view.getId(); if (id == R.id.btnAdd) { addFragment(); } else if (id == R.id.btnDelete) { removeFragment(); } } private void addFragment(){ adapter.addFragment(FragmentCPPayee.newInstance("Title"); adapter.notifyDataSetChanged(); mBinding.tab.setViewPager(mBinding.viewpager); } private void removeFragment(){ adapter.removeItem(mBinding.viewpager.getCurrentItem()); mBinding.tab.setViewPager(mBinding.viewpager); } class ViewPagerAdapter extends FragmentStatePagerAdapter { private final List mFragmentList = new ArrayList<>(); private final List mFragmentTitleList = new ArrayList<>(); public ViewPagerAdapter(FragmentManager manager) { super(manager); } @Override public int getItemPosition(@NonNull Object object) { return PagerAdapter.POSITION_NONE; } @Override public Fragment getItem(int position) { return mFragmentList.get(position); } @Override public int getCount() { return mFragmentList.size(); } public void addFragment(Fragment fragment, String title) { mFragmentList.add(fragment); mFragmentTitleList.add(title); } public void removeItem(int pos) { destroyItem(null, pos, mFragmentList.get(pos)); mFragmentList.remove(pos); mFragmentTitleList.remove(pos); adapter.notifyDataSetChanged(); mBinding.viewpager.setCurrentItem(pos - 1, false); } @Override public CharSequence getPageTitle(int position) { return "Title " + String.valueOf(position + 1); } } } 

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