Android, Cómo mezclar ActionBar.Tab + Ver Pager + ListFragment

¡He estado intentando probar cómo mezclar todas estas cosas juntas y tengo problemas !! Sólo quiero una aplicación con tres pestañas utilizando el ActionBar.Tab. Por ejemplo, estas pestañas pueden ser películas de género Acción, Aventura y Animación, el usuario puede pasar por las pestañas, por lo que utilizará el ViewPager y cada pestaña mostrará una lista de películas de ese género. No es necesario tener tres clases de fragmentos diferentes porque todas las fichas tendrán el mismo formato una lista simple. Y estoy teniendo problemas porque cuando selecciono la segunda pestaña, la posición de onPageSelected es 1,

mViewPager = (ViewPager) findViewById(R.id.pager); mViewPager.setAdapter(mCollectionPagerAdapter); mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { @Override public void onPageSelected(int position) { mActionBar.setSelectedNavigationItem(position); } }); 

Esto hace que la llamada al método public Fragment getItem (int i) dentro de la clase CollectionPagerAdapter, pero entonces el valor de i es 2 NOT 1, por lo que llama a createView para la clase TabFragment con un valor de 2 NOT 1, así que las pestañas No se están actualizando correctamente.

¡¡Cualquier ayuda será muy apreciada!!

Código para crear las pestañas,

 // For each of the sections in the app, add a tab to the action bar. for (int i = 0; i < mCollectionPagerAdapter.getCount(); i++) { mActionBar.addTab(mActionBar.newTab() .setText(mGenres.get(i).getName()) .setTabListener(this)); //Let's request the movies for the first three genres new GetMoviesByGenre().execute(mGenres.get(i).getId()); } 

Cuando se selecciona una pestaña,

 @Override public void onTabSelected(ActionBar.Tab tab, android.app.FragmentTransaction arg1) { //Let's update the dataset for the selected genre TabFragment fragment = (TabFragment) getSupportFragmentManager().findFragmentByTag( "android:switcher:"+R.id.pager+":"+tab.getPosition()); if(fragment != null) // could be null if not instantiated yet { if(fragment.getView() != null) { fragment.updateDisplay(tab.getPosition()); // do what updates are required } } mViewPager.setCurrentItem(tab.getPosition()); } 

Clase CollectionPageAdapter

 public class CollectionPagerAdapter extends FragmentPagerAdapter { final int NUM_ITEMS = 3; // number of tabs List<Fragment> fragments = new ArrayList<Fragment>(); public Fragment getItem(int pos) { return fragments.get(pos); } public void addFragment(Fragment f) { fragments.add(f); } public CollectionPagerAdapter(FragmentManager fm) { super(fm); //Let's add the fragments for (int i=0;i<NUM_ITEMS;i++) { Fragment fragment = new TabFragment(); Bundle args = new Bundle(); args.putInt(TabFragment.ARG_OBJECT, 0); fragment.setArguments(args); addFragment (fragment); } } @Override public int getCount() { return NUM_ITEMS; } 

}

Clase TabFragment

 public class TabFragment extends ListFragment { public static final String ARG_OBJECT = "object"; private MoviesAdapter m_Adapter; private ArrayList <Movie> mMovies = new ArrayList<Movie>(); @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // you only need to instantiate these the first time your fragment is // created; then, the method above will do the rest if (m_Adapter == null) { m_Adapter = new MoviesAdapter(getActivity(), mMovies); } setListAdapter(m_Adapter); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { int position = getArguments().getInt(ARG_OBJECT); // to check is the right fragment View rootView = inflater.inflate(R.layout.tabs, container, false); return rootView; } public void updateDisplay (int type) { GlobalVars gv = (GlobalVars)getActivity().getApplicationContext(); switch (type) { case 0: mMovies = gv.getActionMovies(); break; case 1: mMovies = gv.getAdventureMovies(); break; case 2: mMovies = gv.getAnimationMovies(); break; } m_Adapter.notifyDataSetChanged(); } 

}

No hago lo que estoy haciendo mal, supongo que los fragmentos están desordenados, porque cuando presiono la segunda pestaña, los datos de la primera pestaña se actualiza, y así sucesivamente …

¡Gracias!

En lugar de usar CollectionPageAdapter, cambié para usar la clase TabsAdapter mostrada en la documentación de ViewPager de Android y funciona!

 public class TabsAdapter extends FragmentPagerAdapter implements ActionBar.TabListener, ViewPager.OnPageChangeListener { private final Context mContext; private final ActionBar mActionBar; private final ViewPager mViewPager; private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>(); private final List<Fragment> fragments = new ArrayList<Fragment>(); static final class TabInfo { private final Class<?> clss; private final Bundle args; TabInfo(Class<?> _class, Bundle _args) { clss = _class; args = _args; } } public TabsAdapter(FragmentActivity activity, ViewPager pager) { super(activity.getSupportFragmentManager()); mContext = activity; mActionBar = activity.getActionBar(); mViewPager = pager; mViewPager.setAdapter(this); mViewPager.setOnPageChangeListener(this); } public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) { TabInfo info = new TabInfo(clss, args); tab.setTag(info); tab.setTabListener(this); mTabs.add(info); mActionBar.addTab(tab); notifyDataSetChanged(); } @Override public int getCount() { return mTabs.size(); } @Override public int getItemPosition(Object object) { return POSITION_NONE; } @Override public Fragment getItem(int position) { TabInfo info = mTabs.get(position); Fragment fr = Fragment.instantiate(mContext, info.clss.getName(), info.args); //addFragment (fr, position); return fr; } public void addFragment(Fragment f, int location) { if (fragments.size() == 0) fragments.add(f); else fragments.add(location, f); } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { mActionBar.setSelectedNavigationItem(position); } @Override public void onPageScrollStateChanged(int state) { } @Override public void onTabSelected(Tab tab, android.app.FragmentTransaction ft) { Object tag = tab.getTag(); for (int i=0; i<mTabs.size(); i++) { if (mTabs.get(i) == tag) { updateDatasetMovies (i); mViewPager.setCurrentItem(i); } } } @Override public void onTabReselected(Tab tab, android.app.FragmentTransaction ft) { // TODO Auto-generated method stub } @Override public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft) { // TODO Auto-generated method stub } public void updateDatasetMovies (int pos) { //Let's update the dataset for the selected genre TabFragment fragment = (TabFragment) ((FragmentActivity)mContext).getSupportFragmentManager().findFragmentByTag( "android:switcher:"+R.id.pager+":"+pos); //TabFragment fragment = (TabFragment) getItem(pos); if(fragment != null) // could be null if not instantiated yet { if(fragment.getView() != null) { // no need to call if fragment's onDestroyView() //has since been called. fragment.updateDisplay(pos); // do what updates are required } } } 

Todos los derechos reservados

Estoy de acuerdo con nirvik en esto, sin embargo hay una mejora cruciual que debe hacerse. Esta implementación tiene una falla: al pasar a un fragmento siguiente se invoca el método onPageSelected, que a su vez invoca el método onTabSelected llamando a mActionBar.setSelectedNavigationItem (position) ;. Esto provoca un parpadeo en la animación. Esta:

 viewPager.setCurrentItem(i); 

Debe sustituirse por el siguiente:

 if(i != viewPager.getCurrentItem()) { viewPager.setCurrentItem(i); } 

Resultando en una transición suave.

Puede intentar incluir el código siguiente en su FragmentPagerAdapter y ver si esto soluciona el problema.

 public int getItemPosition(Object object) { return POSITION_NONE; } 

También puede intentar usar un FragmentStatePagerAdapter .

  • Android Viewpager tinder como UI con la apariencia de la pila de tarjetas 3D
  • ¿Cómo puedo poner títulos en ViewPager usando fragmentos?
  • Acceda a la vista de fragmentos de padres de ViewPager en el fragmento secundario de Pager
  • Cómo hacer la transición de viewpager rápido con fragmento?
  • Ver Holder Pattern para ViewPager?
  • Reemplazar la posición de los fragmentos dentro de ViewPager
  • Android: ViewFlipper o ViewPager - ¿Cuál es la mejor opción?
  • Vista personalizada que divide el diseño en diagonal con diferentes vistas secundarias
  • Cómo cambiar las vistas en una implementación de buscador de vista horizontal en Android
  • Implementar vista como ver paginador
  • FragmentStatePagerAdapter fuga de memoria (fragmentos anidados con viewpager)
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.