FragmentPagerAdapter - 当用户转到新标签时如何检测滑动或标签点击?

时间:2015-01-17 20:09:00

标签: android android-fragments android-viewpager android-tabhost android-pageradapter

我有一个MainActivityFragmentPagerAdapter中有三个片段,如下所示。如何通过滑动或单击选项卡,如何找出用户从第一个片段到第二个片段或从第二个片段到第二个片段的时间?我看到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的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);

4 个答案:

答案 0 :(得分:26)

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

除此之外:可以使用ViewPager.setOffScreenLimit()

修改此行为

为了在用户切换网页时收到通知,您实际想要做的是使用OnPageChangeListenerViewPager.addOnPageChangeListener()设置为getItem(),以便在选择页面时收到通知。

答案 1 :(得分:3)

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

        }
    });

答案 2 :(得分:2)

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

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. MainThreeTabAdapter
  2. 延长CachingFragmentPagerAdapter
  3. addOnPageChangeListener添加到ViewPager
  4. onPageSelected方法中查找并与片段进行交互,如下所示:

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

答案 3 :(得分:0)

如果我假设您在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());
        }
});