FragmentPagerAdapter语言 - 当用户转到新选项卡时如何检测滑动或选项卡单击



我有一个MainActivity,它在一个FragmentPagerAdapter中有三个片段,如下所示。如何通过滑动或单击选项卡来了解用户何时从第一个片段转到第二个片段或从第二个片段转到第三个片段?我看到 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;
    }
}

在主活动的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);

仅在创建视图时调用 getItem() 方法。若要了解为什么不调用getItem(),有助于了解ViewPager的默认行为。默认情况下,当您位于ViewPager的特定页面上时,它还会创建此特定页面之前和之后的页面。如果您要按此顺序 [a,b,c] 命名 3 个片段,并且您在页面上 b,由于 ViewPager 片段的默认行为,已经通过调用 getItem(int) 创建了 a 和 c。由于片段已创建,因此不会再收到getItem()

旁白:此行为可以通过ViewPager.setOffScreenLimit()

为了在用户切换页面时收到通知,您实际要做的是使用ViewPager.addOnPageChangeListener()在选择页面时收到通知来设置ViewPager OnPageChangeListener

    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) {
        }
    });

如果我假设你在ViewPager中使用TabLayout,你应该使用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());
        }
});

首先,我想你有以下声明的字段

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)的方法。

如果要获取当前片段的实际实例以直接与之交互,则可以创建自己的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. 将您的MainThreeTabAdapterCachingFragmentPagerAdapter扩展
  2. addOnPageChangeListener添加到ViewPager
  3. 在方法中查找片段并与之交互onPageSelected如下所示:

    public void onPageSelected(int position) {
        final Fragment fragment = adapter.getRegisteredFragment(position);
        if (fragment instanceof NewsFragment) {
            //...
        } else ...
    }
    

最新更新