it-swarm.com.ru

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

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

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

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

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

17
Mohit Charadva

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

Сначала я нашел ширину табуляции и прокрутил ее позицию по ширине на 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);
37
Mohit Charadva

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

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

Также, если вы получаете эту ошибку: «Только исходный поток, создавший иерархию представлений, может касаться его представлений», вы можете использовать этот код для запуска в потоке пользовательского интерфейса:

    // 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();
        }
    });
5
sunlover3

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

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();
                    }
                });
}
3
Ashok Varma

Вышеприведенный ответ не сработает, потому что, во-первых, как упомянул agirardello, вы не должны использовать mTabLayout.getWidth(), так как он не возвращает то, что нам нужно (то есть положение ребенка, на которого вы хотите перейти), а обновленное решение не всегда работает, потому что об ошибке в 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).

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

2
Kayvan N

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

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

Вы вызываете 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();

                }
            });
        }
    }
}

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

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

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

0
RanaUmer

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

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

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

0
locomain

Это решение сработало для меня. Моя ситуация немного отличается, хотя; в моем случае я использую 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;
    }
}
0
Tyler

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

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

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

0
barnabas

Фрагмент кода ниже работает для меня

class TriggerOnceListener(private val v: View, private val block: () -> Unit) : ViewTreeObserver.OnPreDrawListener {
    override fun onPreDraw(): Boolean {
        block()
        v.viewTreeObserver.removeOnPreDrawListener(this)
        return true
    }
}

fun onCreate() {
    val position = ***The tab position you want to scroll to, 29 for your case here***
    tabLayout.let { it.viewTreeObserver.addOnPreDrawListener(TriggerOnceListener(it)
    { it.setScrollPosition(position, 0f, true) } ) }
}

Я погрузился в Tab.select () и обнаружил, что Android использует Tablayout.setScrollPosition () для этой прокрутки. А в onCreate () виджеты не были измерены, вам нужно отложить вызов до завершения компоновки.

0
Kun Zhang