How to scroll tablayout programmatically - Android

前端 未结 13 2157
终归单人心
终归单人心 2021-02-07 00:31

I have created 30 scrollable tabs using tablayout.

So first three tabs are visible on screen and rest of them are invisible which can be scroll using swipe gesture.

13条回答
  •  无人及你
    2021-02-07 00:44

    This solution worked for me. My situation is a little bit different though; in my case, I am using the TabLayout with a ViewPager and adding more views and calling notifyDataSetChange().

    The solution is to set a callback on the observer of TabLayout and scroll when the children are actually added to the TabLayout. Here is my example:

    /**
        Keep in mind this is how I set my TabLayout up...
    
        PagerAdapter pagerAdapter = new PagerAdapter(...);
        ViewPager pager = (ViewPager)findViewById(...);
        pager.setAdapter(pagerAdapter);
    
        TabLayout tabLayout = (TabLayout)findViewById(...);
        tabLayout.setupWithViewPager(pager);
    */
    public void loadTabs(String[] topics) {
        animateTabsOpen(); // Irrelevant to solution
    
        // Removes fragments from ViewPager
        pagerAdapter.clear();
    
        // Adds new fragments to ViewPager
        for (String t : topics)
             pagerAdapter.append(t, new TestFragment());
    
        // Since we need observer callback to still animate tabs when we
        // scroll, it is essential to keep track of the state. Declare this
        // as a global variable
        scrollToFirst = true;
    
        // Alerts ViewPager data has been changed
        pagerAdapter.notifyOnDataSetChanged();
    
        // Scroll to the beginning (or any position you need) in TabLayout
        // using its observer callbacks
        tabs.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                /**
                     We use onGlobalLayout() callback because anytime a tab
                     is added or removed the TabLayout triggers this; therefore,
                     we use it to scroll to the desired position we want. In my
                     case I wanted to scroll to the beginning position, but this
                     can easily be modified to scroll to any position.
                 */
                if (scrollToFirst) {
                    tabs.getTabAt(0).select();
                    tabs.scrollTo(0, 0);
                    scrollToFirst = false;
                }
            }
        });
    }
    

    Here is my code for the PagerAdapter if you need it too lol:

    public class PagerAdapter extends FragmentStatePagerAdapter {
        private List fragments;
        private List titles;
    
    
        public PagerAdapter(FragmentManager fm) {
            super(fm);
            this.fragments = new ArrayList<>();
            this.titles = new ArrayList<>();
        }
    
        /**
         * Adds an adapter item (title and fragment) and
         * doesn't notify that data has changed.
         *
         * NOTE: Remember to call notifyDataSetChanged()!
         * @param title Fragment title
         * @param frag Fragment
         * @return This
         */
        public PagerAdapter append(String title, Fragment frag) {
            this.titles.add(title);
            this.fragments.add(frag);
            return this;
        }
    
        /**
         * Clears all adapter items and doesn't notify that data
         * has changed.
         *
         * NOTE: Rememeber to call notifyDataSetChanged()!
         * @return This
         */
        public PagerAdapter clear() {
            this.titles.clear();
            this.fragments.clear();
            return this;
        }
    
        @Override
        public Fragment getItem(int position) {
            return fragments.get(position);
        }
    
        @Override
        public CharSequence getPageTitle(int position) {
            return titles.get(position);
        }
    
        @Override
        public int getCount() {
            return fragments.size();
        }
    
        @Override
        public int getItemPosition(Object object) {
            int position = fragments.indexOf(object);
            return (position >= 0) ? position : POSITION_NONE;
        }
    }
    

提交回复
热议问题