with viewpager studio practice fragments example best android android-fragments android-viewpager

android - studio - Reemplazar fragmento con otro fragmento dentro de ViewPager



slide android studio (6)

Estoy usando ViewPager junto con FragmentPagerAdapter para alojar tres fragmentos diferentes

[Fragment1][Fragment2][Fragment3]

Lo que intento lograr es reemplazar Fragment1 con un nuevo fragmento, Fragment4, si una tarea específica tiene éxito.

Cuando uso ...

FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction transaction = fragmentManager.beginTransaction(); transaction.replace(R.id.fragment1_layout_id, fragment4); transaction.commit();

..el fragmento se reemplaza maravillosamente y se muestra Fragment4 en lugar de Fragment1. Aunque tan pronto como deslizo todo el camino hasta Fragment3 y luego regreso a Fragment4, Fragment1 ha regresado.

Por otra parte, si uso ...

FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction transaction = fragmentManager.beginTransaction(); transaction.remove(fragment1); transaction.commit();

..Fragment1 se elimina y cuando vuelvo Fragment4 está allí. Entonces, el problema con esta solución es que no pude encontrar una manera de mostrar inmediatamente Fragment4 ya que Fragment1 se eliminó, incluso si lo intenté:

transaction.add(fragment4); transaction.show(fragment4);

Y así es cómo se ve mi implementación de FragmentPagerAdapter en este momento, sin ninguna gestión de transacciones :

public static class PagerAdapter extends FragmentPagerAdapter { public PagerAdapter(FragmentManager fm) { super(fm); } @Override public int getCount() { return VIEW_COUNT; } @Override public Fragment getItem(int position) { Fragment fragment = null; switch (position) { case 0: fragment = Fragment1.newInstance(context_); break; case 1: fragment = Fragment2.newInstance(context_); break; case 2: fragment = Fragment3.newInstance(context_); break; default: break; } return fragment; } }

Editar.

Entonces parece que no estaba totalmente claro con mi pregunta. Decidí eliminar todos los espaguetis que pude crear antes e intenté decir que los había dejado (vea el texto en negrita arriba).

De todos modos aquí es más o menos lo que he estado tratando de hacer dentro de getItem ():

@Override public Fragment getItem(int position) { Fragment fragment = null; switch (position) { case 0: if (!app.isUserLoggedIn) { if (loginFragment_ == null) { loginFragment_ = LoginFragment.newInstance(context_); transaction_ = fragmentManager_.beginTransaction(); if (logoutFragment_ != null) { transaction_.remove(logoutFragment_); logoutFragment_ = null; } transaction_.add(loginFragment_, "login"); transaction_.commit(); } if (fragmentManager_.findFragmentByTag("login") == null) fragment = LoginFragment.newInstance(context_); else fragment = fragmentManager_.findFragmentByTag("login"); } else { if (logoutFragment_ == null) { logoutFragment_ = LogoutFragment.newInstance(context_); transaction_ = fragmentManager_.beginTransaction(); if (loginFragment_ != null) { transaction_.remove(loginFragment_); loginFragment_ = null; } transaction_.add(logoutFragment_, "logout"); transaction_.commit(); } if (fragmentManager_.findFragmentByTag("logout") == null) fragment = LogoutFragment.newInstance(context_); else fragment = fragmentManager_.findFragmentByTag("logout"); } break; case 1: fragment = HomeFragment.newInstance(context_); break; case 2: fragment = RegisterFragment.newInstance(context_); break; default: break; } return fragment; }

Con este código no consigo nada, pero si alguien ve lo que estoy haciendo mal y me gustaría orientarme en la dirección correcta, ¡lo agradecería muchísimo!


¿No debería su declaración getItem devolver fragment4 para el case 0 en algunas circunstancias?


Como dijo Maurycy, debe llamar a mAdapter.notifyDataSetChanged() siempre que quiera decirle a ViewPager que los fragmentos han sido reemplazados. Sin embargo, también debe anular la función abstracta getItemPosition() en su adaptador y devolver POSITION_NONE cuando se le llame con un fragmento viejo, que se ocultará, como argumento. De lo contrario, ViewPager retendrá todos los fragmentos actuales.

Para obtener más información y un código de ejemplo, consulte esta respuesta a una pregunta relacionada .


Consulte mi answer a una pregunta similar sobre cómo insertar / reemplazar pestañas con ViewPager y FragmentPagerAdapter .


Hola, he resuelto este problema usando una lista dentro de mi FragmentPagerAdapter para manejar los diversos fragmentos y luego mi getItem es así ...

public void addScreen(String tag, Class<?> clss, Bundle args){ if(clss!=null){ TabInfo info = new TabInfo(tag, clss, args); screens.add(info); } } @Override public Fragment getItem(int position) { TabInfo info = screens.get(position); return Fragment.instantiate(context, info.clss.getName(), info.args); }

Luego elimino / agrego / reorganizo programáticamente los elementos de la lista (fragmentos) y luego llamo al manejador

mAdapter.notifyDataSetChanged()


Intenta usar FragmentStatePagerAdapter

http://android-developers.blogspot.com/2011_08_01_archive.html

porque eliminará el fragmento a medida que desliza la vista (también cuando llama a getitem), por lo que no necesita eliminarlos explícitamente.

He estado teniendo el mismo problema para mí.

Intento tu código y elimino el bloque if (fragment!=null) y funciona.


Intente establecer OffscreenPageLimit en 5 (o en función de su uso) para evitar que se vuelva a cargar el fragmento, de modo que lo que haya reemplazado permanecerá en lugar de volver a cargarse cuando deslice.

mViewPager.setOffscreenPageLimit(5);