FragmentPagerAdapter – как обнаружить салфетки или вкладку, когда пользователь переходит на новую вкладку?

У меня есть MainActivity , у которого есть три фрагмента в FragmentPagerAdapter как MainActivity ниже. Как я могу узнать, когда пользователь переходит от 1-го фрагмента к второму или от второго к третьему, либо с помощью прокрутки, либо с помощью щелчка по вкладке? Я видел, что метод getItem() не вызывается всегда, поскольку я объявил mViewPager.setOffscreenPageLimit(2) ;

 public class MainThreeTabAdapter extends FragmentPagerAdapter { private final String[] CONTENT = new String[]{"News", "Rewards", "Me"}; public MainThreeTabAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { if (position == 0) { return NewsFragment.newInstance(); } else if (position == 1) { return RewardsFragment.newInstance(); } else if (position == 2) { return MeFragment.newInstance(true, App.getAccountData().getId()); } else { return null; } } @Override public CharSequence getPageTitle(int position) { return CONTENT[position % CONTENT.length]; } @Override public int getCount() { return CONTENT.length; } } 

В MainActivity's onCreate()

  mainThreeTabAdapter = new MainThreeTabAdapter(getFragmentManager()); // Set up the ViewPager with the sections adapter. // this ensures that 2 tabs on each side of current are kept in memory, which is all we need for our case. Default = 1 // this is all taken from the Quickreturn facebook sample app mViewPager.setOffscreenPageLimit(2); mViewPager.setAdapter(mainThreeTabAdapter); 

Solutions Collecting From Web of "FragmentPagerAdapter – как обнаружить салфетки или вкладку, когда пользователь переходит на новую вкладку?"

Метод getItem() вызывается только при создании представления. Чтобы понять, почему getItem() не вызывается, он помогает понять поведение по умолчанию ViewPager . По умолчанию, когда вы находитесь на определенной странице ViewPager он также создает страницы, которые находятся до и после этой конкретной страницы. Если у вас должно было быть 3 фрагмента, названных и в этом порядке [a, b, c], и вы были на странице b, из-за поведения по умолчанию для фрагментов ViewPager a и c уже были бы созданы с вызовом getItem(int) . Поскольку фрагменты уже созданы, вы не получите другого вызова getItem()

Кроме того: это поведение можно изменить с помощью ViewPager.setOffScreenLimit()

То, что вы на самом деле хотите сделать, чтобы получать уведомления, когда пользователь переключает страницы, – это установить OnPageChangeListener в ViewPager используя ViewPager.addOnPageChangeListener() чтобы получать уведомление, когда выбрана страница.

Прежде всего, я предполагаю, что у вас есть следующие объявленные поля

 ViewPager pager; TabLayout tabs; MainThreeTabAdapter adapter; 

Затем вам нужно создать экземпляр адаптера и установить его в пейджер. Здесь вы можете добавить прослушиватель вызова addOnPageChangeListener

 adapter = new MainThreeTabAdapter(getSupportFragmentManager()); pager.setAdapter(adapter); pager.addOnPageChangeListener(/*here is your listener instance*/); tabs.setupWithViewPager(pager); 

Всегда, когда страница переключается на новую, нажимая или нажимая на вкладку, onPageSelected(int position) метод onPageSelected(int position) .

Если вы хотите, чтобы фактический экземпляр текущего фрагмента взаимодействовал с ним напрямую, вы можете создать свой собственный FragmentPagerAdapter который должен кэшировать созданные фрагменты:

 public abstract class CachingFragmentPagerAdapter extends FragmentPagerAdapter { private final SparseArray<Fragment> registeredFragments = new SparseArray<>(); public CachingFragmentPagerAdapter(FragmentManager fm) { super(fm); } @Override public Object instantiateItem(ViewGroup container, int position) { Fragment fragment = (Fragment) super.instantiateItem(container, position); registeredFragments.put(position, fragment); return fragment; } @Override public void destroyItem(ViewGroup container, int position, Object object) { registeredFragments.remove(position); super.destroyItem(container, position, object); } public Fragment getRegisteredFragment(int position) { return registeredFragments.get(position); } public SparseArray<Fragment> getRegisteredFragments() { return registeredFragments; } } 

Таким образом, вы должны

  1. MainThreeTabAdapter свой MainThreeTabAdapter от CachingFragmentPagerAdapter
  2. Добавить addOnPageChangeListener в ViewPager
  3. Найти и взаимодействовать с фрагментом в onPageSelected например, следующим образом:

     public void onPageSelected(int position) { final Fragment fragment = adapter.getRegisteredFragment(position); if (fragment instanceof NewsFragment) { //... } else ... } 
  mViewPager.setAdapter(mSectionsPagerAdapter); mViewPager.setOffscreenPageLimit(4); mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { _position = position; switch (position) { case 0: _header.setButtonVisible(1, View.GONE); break; case 1: _header.setButtonVisible(1, View.GONE); break; case 2: _header.setButtonVisible(1, View.VISIBLE); break; case 3: _header.setButtonVisible(1, View.VISIBLE); break; } } @Override public void onPageScrollStateChanged(int state) { } }); 

Если, как я полагаю, вы используете TabLayout с ViewPager, вы должны использовать addOnTabSelectedListener (). Это будет обрабатывать как явный щелчок на вкладке, так и салфетки.

 mTabLayout.setupWithViewPager(mViewPager); mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override public void onTabSelected(TabLayout.Tab tab) { Logger.d(TAG, "tabSelected: " + tab.getPosition()); } @Override public void onTabUnselected(TabLayout.Tab tab) { Logger.d(TAG, "tabUnselected: " + tab.getPosition()); } @Override public void onTabReselected(TabLayout.Tab tab) { Logger.d(TAG, "tabReselected: " + tab.getPosition()); } });