Как прокрутить табуляцию программно - Android

Я создал 30 прокручиваемых вкладок, используя tablayout.

Таким образом, первые три вкладки видны на экране, а остальные невидимы, и их можно прокручивать с помощью жеста смахивания.

Проблема в том, что я выбираю последнюю вкладку программно, но она не видна (расположение вкладок не прокручивается до последней вкладки).

Как я могу сделать tablayout, чтобы перейти к последней вкладке?

Ответ 1

Я нашел решение.

Сначала я нашел ширину tablayout и прокрутил ее по оси x до ширины и назвал метод select() последней вкладки.

И он отлично работает.

Ниже приведен код.

mTabLayout.setScrollX(mTabLayout.getWidth());
mTabLayout.getTabAt(lastTabIndex).select();

Обновление

Если выше не работает, вы также можете использовать приведенный ниже код, он также работает нормально.

new Handler().postDelayed(
        new Runnable() {
            @Override public void run() {
                mTabLayout.getTabAt(TAB_NUMBER).select();
            }
        }, 100);

Ответ 2

Я нашел это решение для меня:

    TabLayout tabLayout = activity.getTabLayout();
    tabLayout.setSmoothScrollingEnabled(true);
    tabLayout.setScrollPosition(targetChannelPosition, 0f, true);

Кроме того, если вы получите эту ошибку: "Только исходный поток, создавший иерархию представлений, может коснуться его представлений". Вы можете использовать этот код для запуска в потоке Ui:

    // find a way to get the activity containing the tab layout
    TabLayout tabLayout = activity.getTabLayout();
    activity.runOnUiThread(new Runnable()
    {
        @Override
        public void run()
        {
            TabLayout.Tab tab = tabLayout.getTabAt(targetChannelPosition);
            tab.select();
        }
    });

Ответ 3

напишите этот метод в своем пользовательском tablayout (ваш собственный макет, который расширяет tablayout). Таким образом, в будущем вы можете использовать этот метод всякий раз, когда вам нужна установка дублирования кода

public void selectTabAt(int tabIndex) {
        if (tabIndex >= 0 && tabIndex < getTabCount() && getSelectedTabPosition() != tabIndex) {
            final Tab currentTab = getTabAt(tabIndex);
            if (currentTab != null) {
                this.post(new Runnable() {
                    @Override
                    public void run() {
                        currentTab.select();
                    }
                });
            }
        }
    }

Если вы не хотите, чтобы вы использовали CustomLayout. вы можете просто сделать это

final Tab currentTab = mTabLayout.getTabAt(tabIndex);
if(currentTab != null){
     mTabLayout.post(new Runnable() {
                    @Override
                    public void run() {
                        currentTab.select();
                    }
                });
}

Ответ 4

Вышеприведенный ответ не будет работать, потому что сначала, как сказал агирдардо, вы не должны использовать mTabLayout.getWidth(), поскольку он не возвращает то, что нам нужно (которое является положением дочернего элемента, к которому вы хотите прокрутить), и обновленное решение doesn 't всегда работает из-за ошибки в TabLayout (сообщается здесь), но работа вокруг проста.

Вкладки tabLayout не являются прямыми дочерними элементами TabLayout, поэтому нам нужно идти на один уровень глубже, используя

((ViewGroup) mTabLayout.getChildAt(0)).getChildAt(YOUR_DESIRED_TAB_INDEX).getRight()

единственным дочерним элементом tabLayout является TabLayout.SlidingTabStrip, который также является ViewGroup и getRight(), который предоставит нам право самой позиции нашего желаемого вида вкладок. Таким образом, прокрутка к этой позиции даст нам то, что мы желаем. Вот полный код:

int right = ((ViewGroup) mTabLayout.getChildAt(0)).getChildAt(4).getRight();
mTabLayout.scrollTo(right,0);
mTabLayout.getTabAt(4).select();

ПРИМЕЧАНИЕ. Убедитесь, что вы вызываете эти методы после того, как макет утонул (например, onResume, а не onCreate).

Надеюсь, что это поможет.

Ответ 5

Чтобы выбрать последнюю вкладку, используйте tabLayout.getTabAt(Х).select(); где X - последний индекс вкладки

Ответ 6

Вы звоните tab.select() до того, как TabLayout и его дети были фактически измерены и нарисованы? Если это так, то TabLayout не будет анимировать выделение с помощью tab.select() (или предложения Kayvan N scrollTo()). Использование обработчика, вероятно, будет работать, но это не идеальное решение.

Если макет еще не выложен, ViewTreeObserver позволит вам перейти на выбранную вкладку после процесса компоновки завершено.

private void scrollToTabAfterLayout(final int tabIndex) {
    if (getView() != null) {
        final ViewTreeObserver observer = mTabLayout.getViewTreeObserver();

        if (observer.isAlive()) {
            observer.dispatchOnGlobalLayout(); // In case a previous call is waiting when this call is made
            observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                        observer.removeOnGlobalLayoutListener(this);
                    } else {
                        //noinspection deprecation
                        observer.removeGlobalOnLayoutListener(this);
                    }

                    mTabLayout.getTabAt(tabIndex).select();

                }
            });
        }
    }
}

Прокомментируйте, если у вас есть предложения.

Ответ 7

new Handler().postDelayed(
    new Runnable() {
        @Override public void run() {
            mTabLayout.getTabAt(TAB_NUMBER).select();
        }
    }, 100);

Ответ 8

viewpager.setItem(position) также следует установить положение вкладки

Ответ 9

Это решение сработало для меня. Моя ситуация немного отличается; в моем случае я использую TabLayout с ViewPager и добавляю больше просмотров и вызываю notifyDataSetChange().

Решение состоит в том, чтобы установить обратный вызов наблюдателя TabLayout и прокручивать, когда дети фактически добавлены в TabLayout. Вот мой пример:

/**
    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;
            }
        }
    });
}

Вот мой код для PagerAdapter, если вам это тоже нужно lol:

public class PagerAdapter extends FragmentStatePagerAdapter {
    private List<Fragment> fragments;
    private List<String> 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;
    }
}

Ответ 10

Интересно, будет ли это ответ актуальным, так как его приход очень поздно. Я действительно добился этого в С#, используя Xamarin.

tabs.GetChildAt(0).Selected = true;
 viewPager.SetCurrentItem(0, true);

Ответ 11

Если ваш TabLayout используется в сочетании с ViewPager, который является общим, просто добавьте следующее в метод onCreate() в свою активность:

tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout);

Чтобы некоторые из ваших вкладок не показывались, атрибут tabMode имеет значение app:tabMode="scrollable".

Ответ 12

tab = tabLayout.getSelectedTabPosition();
            tab++;
            TabLayout.Tab tabs = tabLayout.getTabAt(tab);
            if (tabs != null) {
                tabs.select();
            }
            else {
                tabLayout.getTabAt(0).select();
            }

если вы хотите перейти на следующую вкладку по событию клика, используйте этот код

Ответ 13

Кто-нибудь может сказать мне, в чем разница между tabLayout. setScrollPosition(); и tabLayout. getTabAt (INT);

потому что я также могу установить tabLayout для указания следующего с помощью setScrollPosition, но проблема этого подхода заключается в том, что этот метод не обновляет Integer, возвращенный tabLayout. getSelectedTabPosition();