Добавление / удаление страниц в ViewPager динамически
Я хотел бы добавить или удалить страницы из моей пейджер динамично. Это возможно?
9 ответов:
да, поскольку ViewPager получает дочерние представления из PagerAdapter, вы можете добавлять новые страницы / удалять страницы на этом и вызывать .notifyDataSetChanged () для его перезагрузки.
да. Вы можете динамически добавлять или удалять представления в 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(object) { return mList.indexOf(object); } else { return POSITION_NONE; } } }
хотя, если вы просто хотите добавить или удалить представление временно из отображения, но не из набора данных PagerAdapter, попробуйте использовать
setPrimaryItem(ViewGroup, int, Object)
для перехода к определенному виду в данных PagerAdapter иdestroyItem(ViewGroup, int, Object)
для удаления вида с экрана.
Да, код должен быть такой:
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, он не обновит экран мгновенно, я не нашел решения для этого.
Я уверен, что вы создали адаптер путем расширения PageAdapter, так что есть один метод:
@Override public void destroyItem(View collection, int position, Object view) { ((ViewPager) collection).removeView((View) view); }
для подробного примера для того же, просто пройти через .
вот альтернативное решение этого вопроса. Мой адаптер:
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);
после советов Пери Хартман, он начал работать после того как я поставил
null
чтобы ViewPager адаптер и поставить адаптер снова после того, как представления удалены. До этого страница 0 не показывала содержимое списка.
во-первых: переопределить метод pagerAdapter "getItemPosition"
@Override public int getItemPosition(Object object) { return POSITION_NONE; } }
во-вторых: удалите привязку данных с адаптером.и вызовите адаптер.notifydatachanged
это решение хорошо работает до сих пор:
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
класс должен содержать геттер и сеттер для вашего
на основе других ответов и других ресурсов я закончил с этим кодом.
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); } }
удалить страницы:
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 имеет один и тот же код.
макеты-это простые макеты ViewPager / Fragment с
android.support.v4.view.ViewPager
С idcontainer
и фрагментTextView
с idsection_label
.ресурсы: