Подтвердить что ты не робот

FragmentPagerAdapter - как определить салфетки или щелчок на вкладке, когда пользователь переходит на новую вкладку?

У меня есть MainActivity, который имеет три фрагмента в FragmentPagerAdapter, как показано ниже. Как я могу узнать, когда пользователь переходит от 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 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);
4b9b3361

Ответ 1

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

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

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

Ответ 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;
    }
}

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

  • расширьте MainThreeTabAdapter от CachingFragmentPagerAdapter
  • добавить addOnPageChangeListener в ViewPager
  • найти и взаимодействовать с фрагментом в onPageSelected, например, следующим образом:

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

Ответ 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) {

        }
    });

Ответ 4

Если, как я полагаю, вы используете 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());
        }
});