viewpager studio sectionspageradapter fragments example android android-viewpager

sectionspageradapter - viewpager android studio



Añadir/Eliminar páginas a ViewPager dinámicamente (9)

Me gustaría agregar o eliminar páginas de mi visor de página dinámicamente. ¿Es eso posible?


Aquí hay una solución alternativa a esta pregunta. Mi adaptador

private class PagerAdapter extends FragmentPagerAdapter implements ViewPager.OnPageChangeListener, TabListener { private List<Fragment> mFragments = new ArrayList<Fragment>(); private ViewPager mPager; private ActionBar mActionBar; private Fragment mPrimaryItem; public PagerAdapter(FragmentManager fm, ViewPager vp, ActionBar ab) { super(fm); mPager = vp; mPager.setAdapter(this); mPager.setOnPageChangeListener(this); mActionBar = ab; } public void addTab(PartListFragment frag) { mFragments.add(frag); mActionBar.addTab(mActionBar.newTab().setTabListener(this). setText(frag.getPartCategory())); } @Override public Fragment getItem(int position) { return mFragments.get(position); } @Override public int getCount() { return mFragments.size(); } /** (non-Javadoc) * @see android.support.v4.app.FragmentStatePagerAdapter#setPrimaryItem(android.view.ViewGroup, int, java.lang.Object) */ @Override public void setPrimaryItem(ViewGroup container, int position, Object object) { super.setPrimaryItem(container, position, object); mPrimaryItem = (Fragment) object; } /** (non-Javadoc) * @see android.support.v4.view.PagerAdapter#getItemPosition(java.lang.Object) */ @Override public int getItemPosition(Object object) { if (object == mPrimaryItem) { return POSITION_UNCHANGED; } return POSITION_NONE; } @Override public void onTabSelected(Tab tab, FragmentTransaction ft) { mPager.setCurrentItem(tab.getPosition()); } @Override public void onTabUnselected(Tab tab, FragmentTransaction ft) { } @Override public void onTabReselected(Tab tab, FragmentTransaction ft) { } @Override public void onPageScrollStateChanged(int arg0) { } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageSelected(int position) { mActionBar.setSelectedNavigationItem(position); } /** * This method removes the pages from ViewPager */ public void removePages() { mActionBar.removeAllTabs(); //call to ViewPage to remove the pages vp.removeAllViews(); mFragments.clear(); //make this to update the pager vp.setAdapter(null); vp.setAdapter(pagerAdapter); } }

Código para eliminar y agregar dinámicamente

//remove the pages. basically call to method removeAllViews from ViewPager pagerAdapter.removePages(); pagerAdapter.addPage(pass your fragment);

Después del consejo de Peri Hartman , comenzó a funcionar después de configurar null en el adaptador de ViewPager y volver a colocar el adaptador una vez que se eliminaron las vistas. Antes de esto la página 0 no mostraba los contenidos de su lista.


Basándome en otras respuestas y otros recursos, he terminado con este código.

CustomPagerAdapter :

import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.support.v4.view.PagerAdapter; import android.view.View; import android.view.ViewGroup; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class CustomPagerAdapter extends PagerAdapter { private List<Fragment> pages = new ArrayList<>(); private Map<Fragment, Integer> fragmentsPosition = new HashMap<>(); private Fragment currentPrimaryItem; private FragmentManager fragmentManager; private FragmentTransaction currentTransaction; public CustomPagerAdapter(FragmentManager fragmentManager) { this.fragmentManager = fragmentManager; } @Override public Object instantiateItem(ViewGroup container, int position) { if (currentTransaction == null) { currentTransaction = fragmentManager.beginTransaction(); } Fragment pageFragment = pages.get(position); String tag = pageFragment.getArguments().getString(MainActivity.FRAGMENT_TAG_ARG); Fragment fragment = fragmentManager.findFragmentByTag(tag); if (fragment != null) { if (fragment.getId() == container.getId()) { currentTransaction.attach(fragment); } else { fragmentManager.beginTransaction().remove(fragment).commit(); fragmentManager.executePendingTransactions(); currentTransaction.add(container.getId(), fragment, tag); } } else { fragment = pageFragment; currentTransaction.add(container.getId(), fragment, tag); } if (fragment != currentPrimaryItem) { fragment.setMenuVisibility(false); fragment.setUserVisibleHint(false); } return fragment; } @Override public int getCount() { return pages.size(); } @Override public void destroyItem(ViewGroup container, int position, Object object) { if (currentTransaction == null) { currentTransaction = fragmentManager.beginTransaction(); } currentTransaction.detach((Fragment) object); } @Override public void setPrimaryItem(ViewGroup container, int position, Object object) { Fragment fragment = (Fragment) object; if (fragment != currentPrimaryItem) { if (currentPrimaryItem != null) { currentPrimaryItem.setMenuVisibility(false); currentPrimaryItem.setUserVisibleHint(false); } if (fragment != null) { fragment.setMenuVisibility(true); fragment.setUserVisibleHint(true); } currentPrimaryItem = fragment; } } @Override public void finishUpdate(ViewGroup container) { if (currentTransaction != null) { currentTransaction.commitAllowingStateLoss(); currentTransaction = null; fragmentManager.executePendingTransactions(); } } @Override public boolean isViewFromObject(View view, Object object) { return ((Fragment) object).getView() == view; } @Override public int getItemPosition(Object o) { Integer result = fragmentsPosition.get(o); if (result == null) { return PagerAdapter.POSITION_UNCHANGED; } return result; } // ---------------------------------- Page actions ---------------------------------- public void addPage(Fragment fragment) { fragmentsPosition.clear(); pages.add(fragment); notifyDataSetChanged(); } public void removePage(int position) { fragmentsPosition.clear(); Fragment pageFragment = pages.get(position); String tag = pageFragment.getArguments().getString(MainActivity.FRAGMENT_TAG_ARG); Fragment fragment = fragmentManager.findFragmentByTag(tag); if (fragment != null) { fragmentsPosition.put(fragment, PagerAdapter.POSITION_NONE); } for (int i = position + 1; i < pages.size(); i++) { pageFragment = pages.get(i); tag = pageFragment.getArguments().getString(MainActivity.FRAGMENT_TAG_ARG); fragment = fragmentManager.findFragmentByTag(tag); if (fragment != null) { fragmentsPosition.put(fragment, i - 1); } } pages.remove(position); notifyDataSetChanged(); } }

MainActivity :

import android.os.Bundle; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { public static final String FRAGMENT_TAG_ARG = "tag"; private CustomPagerAdapter mCustomPagerAdapter; private ViewPager mViewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mCustomPagerAdapter = new CustomPagerAdapter(getSupportFragmentManager()); mCustomPagerAdapter.addPage(MainFragment.newInstance("Main_Title")); mCustomPagerAdapter.addPage(SecondaryFragment.newInstance("Secondary_Title")); mViewPager = (ViewPager) findViewById(R.id.container); mViewPager.setAdapter(mCustomPagerAdapter); } }

Para eliminar páginas:

mCustomPagerAdapter.removePage(1);

MainFragment :

import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; public class MainFragment extends Fragment { public static final String FRAGMENT_TAG = "MainFragment"; public static MainFragment newInstance(String text) { return newInstance(text, FRAGMENT_TAG); } public static MainFragment newInstance(String text, String tag) { MainFragment fragment = new MainFragment(); Bundle args = new Bundle(); args.putString("text", text); args.putString(MainActivity.FRAGMENT_TAG_ARG, tag + "_" + fragment.hashCode()); fragment.setArguments(args); return fragment; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_main, container, false); TextView textView = (TextView) rootView.findViewById(R.id.section_label); textView.setText(getArguments().getString("text")); return rootView; } }

SecondaryFragment tiene el mismo código.

Los diseños son simples diseños de ViewPager / Fragment con android.support.v4.view.ViewPager con container identificación y Fragment TextView con id section_label .

Recursos:


Esta solución funciona bien por el momento:

public class CustomPagerAdapter extends PagerAdapter { private final List<Item> objects = new ArrayList<>(); public CustomPagerAdapter(List<Item> objects) { if (objects != null) { this.objects.add(objects); } } @Override public int getCount() { return objects.size(); } @Override public boolean isViewFromObject(View view, Object object) { Item item = (Item) object; ItemView itemView = (ItemView) view; return Objects.equals(itemView.getItem(), item); } @Override public int getItemPosition(Object object) { Item item = (Item) object; int idx = objects.indexOf(item); return idx == -1 ? POSITION_NONE : idx; } @Override public Item instantiateItem(ViewGroup container, int position) { Item item = objects.get(position); final int id = generateViewIdForItem(item); ItemView itemView = new ItemView(container.getContext()); itemView.setId(id); container.addView(itemView); itemView.setItem(item); return item; } @Override public void destroyItem(ViewGroup container, int position, Object object) { Item item = (Item) object; final int id = generateViewIdForItem(item); View view = container.findViewById(id); if (view != null) { container.removeView(view); } } public void update(@Nullable List<Item> objects) { this.objects.clear(); if (objects != null) { this.objects.addAll(objects); } notifyDataSetChanged(); } public void clear() { update(null); } /* add remove/update/add methods if you need, don''t forget to call notifyDataSetChanged */ private static int generateViewIdForItem(Item item) { return Math.abs(item.hashCode()); } }

Tenga en cuenta:

  • Su clase de Item debe contener una implementación correspondiente para los métodos equals y hashCode
  • Su clase ItemView debe contener getter y setter para su objeto Item .

Estoy seguro de que ha creado un adaptador extendiendo PageAdapter, por lo que hay un método:

@Override public void destroyItem(View collection, int position, Object view) { ((ViewPager) collection).removeView((View) view); }

Para obtener un ejemplo detallado de lo mismo, simplemente lea este ejemplo .


Primero: anule el método pagerAdapter "getItemPosition"

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

Segundo: elimine el enlace de datos con el adaptador y llame al adaptador.


Sí, dado que ViewPager obtiene las Vistas secundarias de un PagerAdapter, puede agregar nuevas páginas / eliminar páginas en eso, y llamar a .notifyDataSetChanged () para volver a cargarlo.


Sí, el código debería ser así:

public int addPage(View view, int position) { if ((position >= 0) && (position < getSize())) { myPagerAdapter.mListViews.add(position, view); myPagerAdapter.notifyDataSetChanged(); return position; } else { return -1; } } public View removePage(int position) { if ((position < 0) || (position >= getSize()) || (getSize()<=1)) { return null; } else { if (position == mPager.getCurrentItem()) { if(position == (getSize()-1)) { mPager.setCurrentItem(position-1); } else if (position == 0){ mPager.setCurrentItem(1); } } View tempView = myPagerAdapter.mListViews.remove(position); myPagerAdapter.notifyDataSetChanged(); return tempView; } }

Pero hay un error. Si el elemento actual es 0, y para eliminar la página 0, no se actualizará la pantalla al instante, no he encontrado una solución para esto.


Sí. Puede agregar o eliminar vistas dinámicamente al PagerAdapter que las proporciona al ViewPager y llamar a notifyDataSetChanged() desde el PagerAdapter para alertar al ViewPager afectado sobre los cambios. Sin embargo, cuando lo haga, debe anular la getItemPosition(Object) de PagerAdapter, que les dice si los elementos que están mostrando actualmente han cambiado de posición. De forma predeterminada, esta función está configurada en POSITION_UNCHANGED , por lo que ViewPager no se actualizará inmediatamente si no anula este método. Por ejemplo,

public class mAdapter extends PagerAdapter { List<View> mList; public void addView(View view, int index) { mList.add(index, view); notifyDataSetChanged(); } public void removeView(int index) { mList.remove(index); notifyDataSetChanged(); } @Override public int getItemPosition(Object object)) { if (mList.contains(object) { return mList.indexOf(object); } else { return POSITION_NONE; } } }

Aunque, si simplemente desea agregar o eliminar la vista temporalmente de la pantalla, pero no del conjunto de datos de PagerAdapter, intente usar setPrimaryItem(ViewGroup, int, Object) para ir a una vista particular en los datos de destroyItem(ViewGroup, int, Object) y destroyItem(ViewGroup, int, Object) para eliminar una vista de la pantalla.


@Bind(R.id.pager) ViewPager pager; int pos = pager.getCurrentItem(); pager.removeViewAt(pos);