2008-08-31 5 views
36

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.Mise à jour des icônes des onglets Android

Les TabSpecs sont créés de cette manière dans une méthode setupTabs() 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 y a des cas de couples où je veux être en mesure de changer l'icône qui apparaît dans chaque onglet pendant 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(); 

est-il un moyen de remplacer l'icône qui est affichée sans supprimer et recréer tous les onglets?

Répondre

31

La réponse courte est, vous ne manquez rien. Le SDK Android ne fournit pas une méthode directe pour modifier l'indicateur d'un TabHost après sa création. Le TabSpec est seulement utilisé pour construire l'onglet, donc changer le TabSpec après le fait n'aura aucun effet.

Je pense cependant qu'il existe une solution de contournement. Appelez mTabs.getTabWidget() pour obtenir un objet TabWidget. Ceci est juste une sous-classe de ViewGroup, de sorte que vous pouvez 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 est presque certainement un autre ViewGroup (peut-être un LinearLayout, mais peu importe) qui contient un ImageView et un TextView . Donc, avec un peu de doigté avec le débogueur ou Log.i, vous devriez être en mesure de trouver une recette pour obtenir le ImageView et le modifier directement. L'inconvénient est que si vous ne faites pas attention, la disposition exacte des contrôles dans un onglet pourrait changer et votre application pourrait se casser. Votre solution initiale est peut-être plus robuste, mais là encore, cela peut entraîner d'autres effets indésirables tels que des problèmes de flicker ou de mise au point.

30

Juste pour confirmer dominics réponse, voici sa solution dans le code (qui fonctionne):

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, il est pas poli du tout et l'utilisation de ces indices directs dans getChildAt() est pas agréable du tout. ..

+0

Amélioration mineure - utilisation: TabWidget.getChildTabViewAt (..) au lieu de getChildAt (...) – tonys

6

Voir mon article avec l'exemple de code concernant Customized Android Tabs.

Merci SPCT

+0

Super! Exactement ce que je cherchais. Merci! – Fedor

10

Il est peut-être un peu tard, mais vous voudrez peut-être jeter un oeil à ce Google Group thread

+0

Doux! C'est un peu tard, mais bon à savoir quand même. – lnediger

4

C'est ce que je l'ai fait et ça marche pour moi. J'ai créé cette fonction dans l'activité qui va 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 de texte ou vous pouvez changer les deux, vous pouvez également modifier ceci pour obtenir un enfant onglet. J'ai été particulièrement intéressé par la modification du texte du premier onglet lors de l'exécution.

J'ai appelé cette fonction de l'activité concernée en utilisant cet appel

getParent().updateTab(R.string.tab_bar_analyze); 
4

Essayez ceci:

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

Pour 3 onglets, utilisez ceci:

<?xml version=“1.0” encoding=“UTF-8”?> 

<RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android&#8221; 

android:orientation=“vertical” 

android:layout_width=“fill_parent” 

android:layout_height=“fill_parent” 

android:paddingRight=“4px” 

android:paddingLeft=“4px” > 

<!– –> 

<TextView android:id=“@+id/tab1” 

android:layout_width=“70px” 

android:layout_height=“40px” 

android:layout_alignParentLeft=“true” 

android:layout_marginTop=“1px” 

android:layout_marginLeft=“10px” 

android:background=“@drawable/white” /> 


<TextView android:id=“@+id/text_tab1” 

android:layout_width=“wrap_content” 

android:layout_height=“wrap_content” 

android:layout_alignParentLeft=“true” 

android:layout_marginTop=“10px” 

android:layout_marginLeft=“20px” 

android:textStyle=“bold” 

android:textSize=“17px” 

android:textColor=“@color/orange” 

android:text=“Tab1” /> 


<TextView android:id=“@+id/tab2” 

android:layout_width=“70px” 

android:layout_height=“40px” 

android:layout_alignParentLeft=“true” 

android:layout_marginTop=“1px” 

android:layout_marginLeft=“83px” 

android:background=“@drawable/white” /> 


<TextView android:id=“@+id/text_tab2” 

android:layout_width=“wrap_content” 

android:layout_height=“wrap_content” 

android:layout_alignParentLeft=“true” 

android:layout_marginTop=“10px” 

android:layout_marginLeft=“100px” 

android:textStyle=“bold” 

android:textSize=“17px” 

android:textColor=“@color/blue” 

android:text=“Tab2” /> 


<TextView android:id=“@+id/tab3” 

android:layout_width=“70px” 

android:layout_height=“40px” 

android:layout_alignParentLeft=“true” 

android:layout_marginTop=“1px” 

android:layout_marginLeft=“156px” 

android:background=“@drawable/white” /> 


<TextView android:id=“@+id/text_tab3” 

android:layout_width=“wrap_content” 

android:layout_height=“wrap_content” 

android:layout_marginTop=“10px” 

android:layout_marginLeft=“170px” 

android:textStyle=“bold” 

android:textSize=“17px” 

android:textColor=“@color/green” 

android:text=“Tab3” /> 


<LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android&#8221; 

android:id=“@+id/box_1” 

android:layout_width=“fill_parent” 

android:layout_height=“wrap_content” 

android:layout_below=“@+id/tab1” > 


</LinearLayout> 


</RelativeLayout> 
Questions connexes