web-dev-qa-db-fra.com

TabLayout mettre à jour le contenu de l'onglet avec une vue personnalisée

J'utilise TabLayout de la nouvelle conception de matériau et j'ai un problème. Je ne peux pas mettre à jour le contenu de l'onglet d'une vue personnalisée une fois que l'onglet est créé:

Je peux simplifier ma méthode dans mon PagerAdapter avec

public View setTabView(int position, boolean selected) {
    View v = LayoutInflater.from(context).inflate(R.layout.default_tab_view, null);
    tv = (TextView) v.findViewById(R.id.tabTextView);
    if(selected)
        tv.setText("SELECTED");
    else 
        tv.setText("UNSELECTED");       
    return v;
}

Et en activité, je peux simplifier mon code avec:

TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
ViewPager pager = (ViewPager) findViewById(R.id.viewpager);
PagerAdapter adapter = new PagerAdapter(getSupportFragmentManager());
pager.setAdapter(adapter);
tabLayout.setupWithViewPager(pager);
for (int i = 0; i < tabLayout.getTabCount(); i++) {
    boolean isFirstTab = i == 0;
    TabLayout.Tab tab = tabLayout.getTabAt(i);
    View v;
    v = adapter.setTabView(i, isFirstTab);
    v.setSelected(isFirstTab);
    tab.setCustomView(v);
}

tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        adapter.setTabView(tab.getPosition(), true);
    }

    @Override
    public void onTabUnselected(TabLayout.Tab tab) {
        adapter.setTabView(tab.getPosition(), false);
    }

    @Override
    public void onTabReselected(TabLayout.Tab tab) {

    }
});

Les titres des onglets sont définis dès le démarrage de l'application, mais lorsque je change d'onglet, le contenu reste identique.

23
Giorgio Antonioli

Ok Je pense que c'est un bogue sur la bibliothèque de support de conception Android v22.

Parce que vous parlez des changements de contenu mais je ne peux pas changer la couleur du texte. Une fois que l'onglet est créé et si vous modifiez la mise en page, elle ne sera pas reflétée.

Et comme j'ai vu votre code, vous définissez la disposition personnalisée à l'aide de setCustomView. et pour changer un texte, vous appelez à nouveau la méthode setTabView (). Au lieu de cela, il devrait y avoir une méthode getCustomView () pour que vous puissiez changer la disposition. Il existe une méthode dans TabLayout.Tab.getCustomView mais elle n’a pas d’identificateur et j’ai signalé ce bogue.

https://code.google.com/p/Android/issues/detail?id=177492

[Mise à jour 08-07-2015]

Enfin, bug est accepté par le traking source de bogues Android et marqué comme Future Release. Nous pouvons donc dire que ce bogue n'existera plus dans les bibliothèques futures ..__ et que nous aurons la méthode getCustomView() afin que nous puissions facilement obtenir notre vue personnalisée.

[Mise à jour 18-08-2015]

Enfin, le bogue est résolu Publié dans la bibliothèque de support v23 . Il suffit de mettre à jour la bibliothèque de support à l'aide du gestionnaire de SDK et vous obtenez getCustomView () en tant que public.

il suffit de changer cette ligne en grade 

compile 'com.Android.support:design:23.0.0'

et assurez-vous que compilez et ciblez sdk à 23.

s'il vous plaît vérifier mon code fonctionne bien pour moi

TabLayout.Tab tab=tabLayout.getTabAt(position);         
View view=tab.getCustomView();         
TextView txtCount= (TextView) 
view.findViewById(R.id.txtCount);         
txtCount.setText(count+"");
45
Moinkhan

Bien, j'ai peut-être trouvé une solution très complexe simplement parce que je n'avais pas le temps d'attendre la prochaine version de la bibliothèque de support. Voici ce que j'ai fait:

  1. Définissez l’adaptateur de téléavertisseur sur votre TabLayout tabLayout.setTabsFromPagerAdapter(pagerAdapter);
  2. Ajouter un auditeur à votre ViewPager 

        customViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        }
    
        @Override
        public void onPageSelected(int position) {
            tabLayout.getTabAt(position).select();
        }
    
        @Override
        public void onPageScrollStateChanged(int state) {
        }
    });
    
  3. Ajouter un auditeur à votre TabLayout 

    tabLayout.setOnTabSelectedListener(new
    TabLayout.OnTabSelectedListener() {
    
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            if (!isTabUpdating) {
                isTabUpdating = true;
                final int pos = tab.getPosition();
                customViewPager.setCurrentItem(pos);
    
                // Clears and populates all tabs
                tabLayout.setTabsFromPagerAdapter(pagerAdapter);
                invalidateTabs(pos);
            }
        }
    
        @Override
        public void onTabUnselected(TabLayout.Tab tab) {
        }
    
        @Override
        public void onTabReselected(TabLayout.Tab tab) {
            if (!isTabUpdating) {
                isTabUpdating = true;
                final int pos = tab.getPosition();
                customViewPager.setCurrentItem(pos);
    
                // Clears and populates all tabs
                tabLayout.setTabsFromPagerAdapter(pagerAdapter);
                invalidateTabs(pos);
            }
        }
    });
    
  4. Ajouter une méthode pour re-dessiner tous les onglets 

    private void invalidateTabs(int selected) {
      for (int i = 0; i < tabLayout.getTabCount(); i++) {
          tabLayout.getTabAt(i).setCustomView(pagerAdapter.getTabView(i, i == selected));
      }
      isTabUpdating = false;
    }
    

Ok, alors laissez-moi vous expliquer un peu. Tout d’abord, vous vous demandez peut-être pourquoi j’ai utilisé setTabsFromPagerAdapter() au lieu de setupWithViewPager. Au début, j’utilisais setupWithViewPager mais d’une certaine manière, cela ne fonctionnait pas correctement avec mon téléavertisseur et le premier élément ne pouvait pas être sélectionné. 

La deuxième chose que vous pourriez admettre: chaque fois que je sélectionne un onglet, je les supprime tous. Eh bien, c’était un peu un problème facile, vous voyez les sources Android lorsque vous appelez Tab.setCustomView(View). Il vérifie le parent de la vue et si ce n’est pas nul, il supprime toutes les vues d’enfant. Toutefois, si vous transmettez un élément nouvellement instancié, vous allez ajouter une autre vue au lieu de remplacer l’ancienne: 

    View custom = tab.getCustomView();
        if(custom != null) {
            ViewParent icon = custom.getParent();
            if(icon != this) {
                if(icon != null) {
                    // You wont get here
                    ((ViewGroup)icon).removeView(custom);
                }

                this.addView(custom);
            }
     ...

Alors, j'ai fini par configurer moi-même tous les écouteurs et recréer tous les onglets à chaque changement de page/onglet. Ce n’est PAS une bonne solution, mais il est impossible d’attendre que Google mette à jour sa bibliothèque. C’est probablement la seule solution pour obtenir un tel effet. (Juste au cas où vous vous demanderiez pourquoi c'est si compliqué - il me fallait des onglets avec des vues personnalisées (texte + image) pouvant changer leurs propriétés d'affichage (couleur de la police, image) lorsqu'elles sont sélectionnées/désélectionnées)

BTW - Voici la méthode getTabView(...) de la 4ème étape:

public View getTabView(int pos, boolean isSeleted) {
    View tabview = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout
                    .tab_sessioninfo,
            null, false);
    final ImageView ivTabIcon = (ImageView) tabview.findViewById(R.id.iv_tab_icon);
    final TextView tvTabTittle = (TextView) tabview.findViewById(R.id.tv_tab_title);

    if (isSeleted) {
        tvTabTittle.setTextColor(context.getResources().getColor(R.color.tab_indicator));
    }

    switch (pos) {
        case 0:
            tvTabTittle.setText("1st Tab");
            ivTabIcon.setImageResource(isSeleted ? R.drawable.ic_icon1_selected : R.drawable.ic_icon1);
            break;

        case 1:
            tvTabTittle.setText("2nd Tab");
            ivTabIcon.setImageResource(isSeleted ? R.drawable.ic_icon2_selected : R.drawable.ic_icon2);
            break;

        case 2:
            tvTabTittle.setText("3rd Tab");
            ivTabIcon.setImageResource(isSeleted ? R.drawable.ic_icon3_selected : R.drawable.ic_icon3);
            break;
    }

    return tabview;
}

P.S. Si vous connaissez une meilleure solution pour tout cela, faites-le-moi savoir!

METTRE &AGRAVE; JOUR

Une meilleure solution pourrait être approchée en utilisant Reflection:

  1. Installation facile

    tabLayout.setupWithViewPager(customViewPager);
    customViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        }
    
        @Override
        public void onPageSelected(int position) {
            for (int i = 0; i <tabLayout.getTabCount(); i++){
                updateTab(tabLayout.getTabAt(i), position == i);
            }
        }
    
        @Override
        public void onPageScrollStateChanged(int state) {
        }
    });
    
  2. Onglet Mise à jour

    private void updateTab(TabLayout.Tab tab, boolean isSelected){
      Method method = null;
      try {
          method = TabLayout.Tab.class.getDeclaredMethod("getCustomView", null);
          method.setAccessible(true);
    
          View tabview = (View) method.invoke(tab, null);
    
          final ImageView ivTabIcon = (ImageView) tabview.findViewById(R.id.iv_tab_icon);
          final TextView tvTabTittle = (TextView) tabview.findViewById(R.id.tv_tab_title);
    
          if (isSeleted) {
              tvTabTittle.setTextColor(context.getResources().getColor(R.color.tab_indicator));
          }
    
          switch (pos) {
          case 0:
                tvTabTittle.setText("1st Tab");
                ivTabIcon.setImageResource(isSeleted ? R.drawable.ic_icon1_selected : R.drawable.ic_icon1);
                break;
    
          case 1:
                tvTabTittle.setText("2nd Tab");
                ivTabIcon.setImageResource(isSeleted ? R.drawable.ic_icon2_selected : R.drawable.ic_icon2);
                break;
    
          case 2:
                tvTabTittle.setText("3rd Tab");
                ivTabIcon.setImageResource(isSeleted ? R.drawable.ic_icon3_selected : R.drawable.ic_icon3);
                break;
          }
    
          tab.setCustomView(tabview);
      } catch (Exception e) {
          e.printStackTrace();
      }
    }
    

METTRE &AGRAVE; JOUR

La nouvelle bibliothèque de support a une méthode publique pour getCustomView(); vous n'avez donc plus besoin de réfléchir!

7
Paul Freez

Jetez un coup d'œil à Réponse vous devez paramétrer la mise en page comme vous le souhaitez. Si vous souhaitez modifier le contenu de l'onglet, apportez les modifications dans Tab.setOnTabSelectedListener ().

tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        if(tab.getPosition()==1){
                tabLayout.setTabTextColors(ContextCompat.getColor(getActivity(), R.color.unselected_tab),ContextCompat.getColor(getActivity(), R.color.tab_selection));
            }else{
                tabLayout.setTabTextColors(ContextCompat.getColor(getActivity(), R.color.unselected_tab),ContextCompat.getColor(getActivity(), R.color.white));

            }

 // same thing goes with other tabs too
 // Just change your tab text on selected/deselected as above

    }

    @Override
    public void onTabUnselected(TabLayout.Tab tab) {
        tab.setCustomView(null);
    }

    @Override
    public void onTabReselected(TabLayout.Tab tab) {

    }
});
0
Tara

s'il vous plaît vérifier mon code fonctionne bien pour moi

TabLayout.Tab tab=tabLayout.getTabAt(position);         
View view=tab.getCustomView();         
TextView txtCount= (TextView) view.findViewById(R.id.txtCount);         
txtCount.setText(count+"");
0
Dalvendra Singh