Mise à jour des icônes des onglets Android
-
09-06-2019 - |
Question
J'ai une activité qui a un TabHost contenant un ensemble de TabSpecs, chacun avec une liste contenant les éléments à afficher par l'onglet.Lorsque chaque TabSpec est créé, je définis une icône à afficher dans l'en-tête de l'onglet.
Les TabSpecs sont ainsi créées au sein d'un setupTabs()
méthode qui boucle pour créer le nombre approprié d'onglets :
TabSpec ts = mTabs.newTabSpec("tab");
ts.setIndicator("TabTitle", iconResource);
ts.setContent(new TabHost.TabContentFactory(
{
public View createTabContent(String tag)
{
...
}
});
mTabs.addTab(ts);
Il existe quelques cas où je souhaite pouvoir modifier l'icône qui s'affiche dans chaque onglet lors de l'exécution de mon programme.Actuellement, je supprime tous les onglets et j'appelle à nouveau le code ci-dessus pour les recréer.
mTabs.getTabWidget().removeAllViews();
mTabs.clearAllTabs(true);
setupTabs();
Existe-t-il un moyen de remplacer l'icône affichée sans supprimer ni recréer tous les onglets ?
La solution
La réponse courte est que vous ne manquez rien.Le SDK Android ne fournit pas de méthode directe pour modifier l'indicateur d'un TabHost
après sa création.Le TabSpec
n'est utilisé que pour construire l'onglet, donc changer le TabSpec
après coup, cela n'aura aucun effet.
Je pense cependant qu'il existe une solution de contournement.Appel mTabs.getTabWidget()
pour obtenir un TabWidget
objet.Ceci est juste une sous-classe de ViewGroup
, pour que tu puisses appeler getChildCount()
et getChildAt()
pour accéder aux onglets individuels dans le TabWidget
.Chacun de ces onglets est également une vue, et dans le cas d'un onglet avec un indicateur graphique et une étiquette de texte, il s'agit presque certainement d'un autre ViewGroup
(peut-être un LinearLayout
, mais ce n'est pas grave) qui contient un ImageView
et un TextView
.Donc, en jouant un peu avec le débogueur ou Log.i
, vous devriez être capable de trouver une recette pour obtenir le ImageView
et changez-le directement.
L'inconvénient est que si vous ne faites pas attention, la disposition exacte des contrôles dans un onglet peut changer et votre application peut tomber en panne.Votre solution initiale est peut-être plus robuste, mais là encore, elle peut entraîner d'autres effets secondaires indésirables tels que des problèmes de scintillement ou de mise au point.
Autres conseils
Juste pour confirmer la réponse de Dominique, voici sa solution en code (qui fonctionne réellement) :
tabHost.setOnTabChangedListener(new OnTabChangeListener() {
public void onTabChanged(String tabId) {
if (TAB_MAP.equals(tabId)) {
ImageView iv = (ImageView) tabHost.getTabWidget().getChildAt(0).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_map_black));
iv = (ImageView) tabHost.getTabWidget().getChildAt(1).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_list_white));
} else if (TAB_LIST.equals(tabId)) {
ImageView iv = (ImageView) tabHost.getTabWidget().getChildAt(0).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_map_white));
iv = (ImageView) tabHost.getTabWidget().getChildAt(1).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_list_black));
}
}
});
Bien sûr, ce n'est pas du tout raffiné et utiliser ces indices directs dans getChildAt() n'est pas du tout agréable...
Il est peut-être un peu tard mais tu devrais peut-être jeter un oeil à ce fil
http://groups.google.com/group/android-developers/browse_thread/thread/ef3bdebcb715b385
Voir mon article avec un exemple de code concernant Onglets Android personnalisés.
Merci spct
C'est ce que j'ai fait et cela fonctionne pour moi.J'ai créé cette fonction dans l'activité qui s'étend de TabBarActivity
public void updateTab(int stringID) {
ViewGroup identifyView = (ViewGroup)getTabWidget().getChildAt(0);
TextView v = (TextView)identifyView.getChildAt(identifyView.getChildCount() - 1);
v.setText(stringID);
}
Vous pouvez modifier cette fonction pour changer l'image au lieu du texte ou vous pouvez modifier les deux, vous pouvez également la modifier pour obtenir n'importe quel onglet enfant.J'étais particulièrement intéressé par la modification du texte du premier onglet au moment de l'exécution.
J'ai appelé cette fonction à partir de l'activité concernée en utilisant cet appel
getParent().updateTab(R.string.tab_bar_analyze);
Essaye ça:
tabHost.setOnTabChangedListener(new OnTabChangeListener() {
public void onTabChanged(String tabId) {
if (TAB_MAP.equals(tabId)) {
ImageView iv = (ImageView) tabHost.getTabWidget().getChildAt(0).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_map_black));
iv = (ImageView) tabHost.getTabWidget().getChildAt(1).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_list_white));
} else if (TAB_LIST.equals(tabId)) {
ImageView iv = (ImageView) tabHost.getTabWidget().getChildAt(0).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_map_white));
iv = (ImageView) tabHost.getTabWidget().getChildAt(1).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_list_black));
}
}
});