Я хотел бы добавить или удалить страницы из моего пейджера просмотра динамически. Возможно ли это?
Добавление/удаление страниц в ViewPager динамически
Ответ 1
Да, поскольку ViewPager получает дочерние представления из PagerAdapter, вы можете добавлять к нему новые страницы/удалять страницы и вызывать .notifyDataSetChanged(), чтобы перезагрузить его.
Ответ 2
Да. Вы можете динамически добавлять или удалять представления в PagerAdapter, который передает их в ViewPager, и вызывать notifyDataSetChanged()
из PagerAdapter, чтобы предупредить затронутый ViewPager об изменениях. Однако, когда вы это делаете, вы должны переопределить getItemPosition(Object)
PagerAdapter, который сообщает им, изменились ли позиции, которые они сейчас показывают, изменили позиции. По умолчанию эта функция установлена на POSITION_UNCHANGED
, поэтому ViewPager не будет обновляться немедленно, если вы не переопределите этот метод. Например,
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((View) object) {
return mList.indexOf((View) object);
} else {
return POSITION_NONE;
}
}
}
Хотя, если вы просто хотите временно добавить или удалить представление с дисплея, но не из набора данных PagerAdapter, попробуйте использовать setPrimaryItem(ViewGroup, int, Object)
для перехода к определенному представлению в данных PagerAdapter и destroyItem(ViewGroup, int, Object)
для удаления вид с дисплея.
Ответ 3
Да, код должен выглядеть следующим образом:
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;
}
}
Но есть ошибка. Если текущий элемент равен 0, и для удаления страницы 0 он не будет обновлять экран мгновенно, я не нашел для этого решения.
Ответ 4
Я уверен, что вы создали адаптер, расширив PageAdapter, поэтому существует один метод:
@Override
public void destroyItem(View collection, int position, Object view) {
((ViewPager) collection).removeView((View) view);
}
Для более подробного примера для этого просто перейдите этот пример.
Ответ 5
Здесь альтернативное решение этого вопроса. Мой адаптер:
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);
}
}
Код для удаления и добавления динамически
//remove the pages. basically call to method removeAllViews from ViewPager
pagerAdapter.removePages();
pagerAdapter.addPage(pass your fragment);
После совета Peri Hartman он начал работать после того, как я установил null
в адаптер ViewPager и снова установил адаптер после удаления просмотров. До этого страница 0 не отображает содержимое списка.
Ответ 6
Сначала: переопределить метод pagerAdapter "getItemPosition"
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
Во-вторых: удалите привязку данных с помощью адаптера. и call adapter.notifydatachanged
Ответ 7
@Bind(R.id.pager)
ViewPager pager;
int pos = pager.getCurrentItem();
pager.removeViewAt(pos);
Ответ 8
Это решение работает до сих пор:
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());
}
}
Обратите внимание:
- Ваш класс
Item
должен содержать соответствующую реализацию для методовequals
иhashCode
- Ваш класс
ItemView
должен содержать getter и setter для вашего объектаItem
.