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.
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);
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();
}
});
é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();
}
});
}
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.
Pour sélectionner le dernier onglet, utilisez tabLayout.getTabAt (X).sélectionnez(); où X est le dernier onglet index
Ê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.
new Handler().postDelayed(
new Runnable() {
@Override public void run() {
mTabLayout.getTabAt(TAB_NUMBER).select();
}
}, 100);
viewpager.setItem(position)
devrait également définir la position de l'onglet
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;
}
}
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);
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"
.