Use the tabrayout method setupWithViewPager() with caution

Posted by pfchin on Wed, 01 Apr 2020 23:51:31 +0200

  • Talayout usually uses setupWithViewPager()
ViewPager viewPager=(ViewPager)findViewById(R.id.view_pager);
TabLayout tabContainView = (TabLayout) findViewById(R.id.pick_school_category_contain);
viewPager.setAdatper(new FragmentStatePagerAdapter(FragmentManager,fragments));
tabContainView. setupWithViewPager(viewPager);
  • View the source code of the setupWithViewPager() method
 public void setupWithViewPager(@NonNull ViewPager viewPager) {
        final PagerAdapter adapter = viewPager.getAdapter();
        if (adapter == null) {
            throw new IllegalArgumentException("ViewPager does not have a PagerAdapter set");
        }

        // First we'll add Tabs, using the adapter's page titles
        setTabsFromPagerAdapter(adapter);

        // Now we'll add our page change listener to the ViewPager
        viewPager.addOnPageChangeListener(new TabLayoutOnPageChangeListener(this));

        // Now we'll add a tab selected listener to set ViewPager's current item
        setOnTabSelectedListener(new ViewPagerOnTabSelectedListener(viewPager));

        // Make sure we reflect the currently set ViewPager item
        if (adapter.getCount() > 0) {
            final int curItem = viewPager.getCurrentItem();
            if (getSelectedTabPosition() != curItem) {
                selectTab(getTabAt(curItem));
            }
        }
    }
  • You'll find three pits

    • setTabsFromPagerAdapter
    public void setTabsFromPagerAdapter(@NonNull PagerAdapter adapter) {
        removeAllTabs();
        for (int i = 0, count = adapter.getCount(); i < count; i++) {
            addTab(newTab().setText(adapter.getPageTitle(i)));
        }
    }
    
    

    removeAllTabs(), that is to say, delete all the previous views added by tabrayout. That is to say, no matter how to deal with view before, it will be killed. Then set to the title returned by PagerAdapter

    • setOnTabSelectedListener(new ViewPagerOnTabSelectedListener(viewPager));

      public static class ViewPagerOnTabSelectedListener implements TabLayout.OnTabSelectedListener {
      private final ViewPager mViewPager;
      
      public ViewPagerOnTabSelectedListener(ViewPager viewPager) {
          mViewPager = viewPager;
      }
      
      @Override
      public void onTabSelected(TabLayout.Tab tab) {
          mViewPager.setCurrentItem(tab.getPosition());
      }
      
      @Override
      public void onTabUnselected(TabLayout.Tab tab) {
          // No-op
      }
      
      @Override
      public void onTabReselected(TabLayout.Tab tab) {
          // No-op
      }
      

    }
    ````
    It's not a big deal here. The most important thing is that you can set the time to monitor when you click tabley ot. By default, the viewpager is scrolling. Rewrite his method

    • selectTab(getTabAt(curItem));
    if (adapter.getCount() > 0) {
            final int curItem = viewPager.getCurrentItem();
            if (getSelectedTabPosition() != curItem) {
                selectTab(getTabAt(curItem));
            }
        }
    

    The most important thing here is to select the first one by default for the first time. The first time some viewpager are selected is not the first time. This is a big problem, which is equivalent to two clicks of viewpager.

    • Sharing this pit is mainly for you to fill in in advance. In the future, you can't be lazy just to save code and forget to see if there is a problem with the code of the encapsulated method.