2011-09-16 20 views
23

estoy usando un ViewPager junto con un FragmentPagerAdapter para albergar tres fragmentos diferentesReemplazar fragmento con otro fragmento en el interior ViewPager

[Fragment1][Fragment2][Fragment3] 

Lo que estoy tratando de lograr es reemplazar con éxito Fragment1 con un fragmento completamente nuevo, Fragmento4, 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(); 

.the fragmento se sustituye muy bien y Fragment4 se muestra en lugar de Fragment1. Aunque en cuanto me desliza el dedo hacia a Fragment3 y luego de vuelta a Fragment4, Fragment1 ha hecho una reaparición.

Por otra parte, si uso ..

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

..Fragment1 se retira y cuando vuelva Fragment4 está allí. Por lo que el problema de esta solución es que no pude encontrar una manera de mostrar de inmediato Fragment4 medida que se retira Fragment1, aunque lo intentara:

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

Y aquí es como mi aplicación FragmentPagerAdapter parece que en este momento, sin cualquier transacción de gestión de:

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.

por lo que parece que no estaba totalmente claro con mi pregunta. Decidí eliminar todos los espaguetis que logró crear antes y trató de afirmar que los había dejado fuera (véase el texto en negrita arriba).

De todos modos aquí es más o menos lo que he estado tratando de hacer dentro 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 hecho, pero si alguien ve lo que estoy haciendo mal y me gustaría señalar en la dirección correcta, ¡lo agradecería mucho!

+0

Creo que debería cambiar getItem en PagerAdapter. Hay un fragmento devuelto que debe ser visible. – pawelzieba

+0

@dziobas Es exactamente donde he estado tratando de hacer la magia que describí en mi pregunta, sin suerte. – velu

+0

se llama a fragmento2 cuando hago clic en la pestaña 1, no sé por qué se llama tab2? es un error del adaptador? –

Respuesta

10

Trate de usar FragmentStatePagerAdapter

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

coz que eliminará el fragmento al pasarlo a través de la vista (también cuando se llama GetItem), por lo que no es necesario para eliminar de forma explícita por sí mismo.

He tenido el mismo problema que funciona para mí.

que probar su código y quite el bloque if (fragment!=null) y funciona.

+0

¿Puedes mostrar algún código por favor? Estaría muy agradecido, porque seguí tus pasos y no obtuve lo que quería ... – cesards

0

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

+0

Sí, debería y he estado tratando de encontrar la forma correcta de hacerlo durante todo el día. Actualicé mi pregunta y agregué cómo he estado tratando de hacerlo hasta ahora. – velu

0

Hey 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 se quita mediante programación/añadir/reorganizar los elementos de la lista (fragmentos) y luego llamar al manejador

mAdapter.notifyDataSetChanged() 
3

Como Maurycy dijo, es necesario llamar a mAdapter.notifyDataSetChanged() cada vez que quiere decirle al 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, vea this answer a un related question.

0

Por favor, consulte mi answer a una pregunta similar sobre cómo insertar/reemplazar pestañas con un ViewPager y FragmentPagerAdapter.

0

Intenta configurar OffScreenPageLimit en 5 (o en función de tu estuche de uso) para evitar que se vuelva a cargar el fragmento para que lo que hayas reemplazado permanezca en lugar de volver a cargarse cuando deslizas el dedo.

mViewPager.setOffscreenPageLimit(5); 
Cuestiones relacionadas