Comment faire défiler tablayout programatically-Android

j'ai créé 30 onglets avec tablayout.

ainsi les trois premières onglets sont visibles à l'écran et les autres sont invisibles qui peuvent être défilées en utilisant le geste de glisser.

le problème est quand je sélectionne le dernier onglet de façon programmatique, mais il n'est pas visible (la mise en page de l'onglet ne se fait pas défiler vers le dernier onglet).

Comment puis-je faire défiler tablayout vers le dernier onglet?

Merci d'avance.

15
demandé sur Mohit Charadva 2015-07-16 10:59:51

11 réponses

j'ai trouvé la solution.

tout d'abord j'avais trouvé la largeur de tablayout et faire défiler sa position x à la largeur et que appelé la méthode select() du dernier onglet.

Et il fonctionne très bien.

ci-dessous est le code.

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

mise à Jour:

Si ci-dessus ne fonctionne pas, vous pouvez utiliser le code ci-dessous ainsi, il est aussi bien fonctionner.

new Handler().postDelayed(
        new Runnable() {
            @Override public void run() {
                mTabLayout.getTabAt(TAB_NUMBER).select();
            }
        }, 100);
30
répondu Mohit Charadva 2015-09-21 20:38:02

j'ai trouvé cette solution pour moi:

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

aussi, si vous recevez cette erreur: "seul le thread original qui a créé une hiérarchie de vues peut toucher ses vues.", vous pouvez utiliser ce code, afin de l'exécuter sur le thread de l'Interface utilisateur:

    // 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
répondu sunlover3 2016-02-17 14:41:29

écrivez cette méthode dans votre tablayout personnalisé (votre propre mise en page qui étend tablayout). Ainsi, à l'avenir, vous pouvez utiliser cette méthode chaque fois que vous avez besoin d'instad de la duplication de code

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

si vous ne voulez pas que vous utilisiez CustomLayout. tu peux faire ça

final Tab currentTab = mTabLayout.getTabAt(tabIndex);
if(currentTab != null){
     mTabLayout.post(new Runnable() {
                    @Override
                    public void run() {
                        currentTab.select();
                    }
                });
}
3
répondu Ashok Varma 2016-05-09 10:02:12

la réponse ci-dessus ne fonctionnerait pas parce que d'abord comme agirardello a mentionné que vous ne devriez pas utiliser mTabLayout.getWidth() puisqu'il ne renvoie pas ce dont nous avons besoin (c'est la position de l'enfant vers lequel vous voulez faire défiler) et que la solution mise à jour ne fonctionne pas toujours à cause d'un bug dans TabLayout (rapporté ici) mais un travail de contournement est simple.

les onglets sur le tabLayout ne sont pas des enfants directs du TabLayout donc nous devons aller un niveau plus profond en utilisant

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

la le seul enfant du couple tabLayout est un TabLayout.SlidingTabStrip qui est aussi un ViewGroup et getRight() nous donnera la bonne position de la vue tab désirée. Donc défiler à cette position nous donnera ce que nous désirons. Voici un code complet:

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

NOTE: assurez-vous que vous appelez ces méthodes après que la mise en page a été noyée (comme onResume et pas onCreate)

J'espère que cela vous aidera.

2
répondu Kayvan N 2015-09-21 21:09:32

Pour sélectionner le dernier onglet, utilisez tabLayout.getTabAt (X).sélectionnez(); où X est le dernier onglet index

1
répondu jomartigcal 2015-07-16 08:15:31

Êtes-vous appeler tab.select() avant que le TabLayout et ses enfants aient été mesurés et dessinés? Si c'est le cas, votre TabLayout ne s'animera pas à la sélection avec tab.select()(ou la suggestion de Kayvan N de scrollTo()). Utiliser un Handler marchera probablement, mais ce n'est pas la solution idéale.

pourvu que la mise en page n'ait pas encore été faite, un ViewTreeObserver vous permettra de passer à l'onglet sélectionné une fois le processus de mise en page terminé.

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();

                }
            });
        }
    }
}

s'il vous Plaît commenter si vous avez des suggestions.

1
répondu Matthew Sisinni 2016-01-14 02:16:43
new Handler().postDelayed(
    new Runnable() {
        @Override public void run() {
            mTabLayout.getTabAt(TAB_NUMBER).select();
        }
    }, 100);
1
répondu Hai Rom 2016-06-14 09:55:04

viewpager.setItem(position) devrait également définir la position de l'onglet

0
répondu locomain 2016-05-09 11:11:38

Cette solution a fonctionné pour moi. Ma situation est un peu différente cependant; dans mon cas, j'utilise TabLayout avec un ViewPager et j'ajoute plus de vues et j'appelle notifyDataSetChange().

la solution est de mettre un callback sur L'observateur de TabLayout et de faire défiler lorsque les enfants sont réellement ajoutés à TabLayout. Voici mon exemple:

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

Voici mon code pour le PagerAdapter si vous en avez besoin trop 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
répondu Tyler 2016-06-03 21:00:35

je me demande si cette réponse sera pertinente puisqu'elle arrive très tard. Je l'ai fait en C# en utilisant de la Xamarine.

tabs.GetChildAt(0).Selected = true;
 viewPager.SetCurrentItem(0, true);
0
répondu uchenna nnodim 2017-01-03 22:52:37

Si votre TabLayout est utilisé en conjonction avec un ViewPager, qui est commun, il suffit d'ajouter ce qui suit dans le onCreate() méthode dans votre Activité:

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

que certains de vos onglets ne sont pas affichés indique que l'attribut tabMode est défini à app:tabMode="scrollable".

0
répondu barnabas 2017-03-30 21:17:09