C'est ainsi que j'ai configuré le TabHost pour afficher les onglets sur la gauche de l'écran, avec les onglets empilés verticalement.
Il est nécessaire de configurer 2 configurations différentes pour l'activité, l'une en mode portrait («normal»), l'autre en mode paysage. Cela implique pas utilisez TabActivity.
J'ai copié la disposition utilisée par TabActivity dans mon propre projet et l'ai appelé main_view.xml (stocké dans res/layout). Ici, il est:
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tabHost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TabWidget android:id="@android:id/tabs"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="0" />
<FrameLayout android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"/>
</LinearLayout>
</TabHost>
Il faut réutiliser les ids Android onglets et tabcontent.
Dans le paysage, j'ai changé cela en inversant les attributs de hauteur de mise en page/largeur pour tous les contrôles et réglage de l'orientation des LinearLayout à l'horizontale (la TabWidget et FrameLayout doit être à côté de l'autre, à l'horizontale). Voici le résultat, dans res/mise en terre, aussi appelé main_view.xml:
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tabHost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TabWidget android:id="@android:id/tabs"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_weight="0" />
<FrameLayout android:id="@android:id/tabcontent"
android:layout_height="match_parent"
android:layout_width="0dip"
android:layout_weight="1"/>
</LinearLayout>
</TabHost>
Notez que si vous voulez que les onglets à droite, vous mettez le TabWidget après la FrameLayout dans le fichier XML au dessus.
TabWidget est lui-même un LinearLayout. Notez que je n'ai pas défini l'orientation en XML. Ceci parce que TabWidget le fait dans son propre code (oui, il est codé en dur). Pour contrer cela, il faut redéfinir l'orientation dans le code. Voici comment je l'ai fait dans mon activité oncreate
setContentView(R.layout.main_view);
final TabHost tabHost = (TabHost) findViewById(R.id.tabHost);
tabHost.setup();
Resources res = getResources();
Configuration cfg = res.getConfiguration();
boolean hor = cfg.orientation == Configuration.ORIENTATION_LANDSCAPE;
if (hor) {
TabWidget tw = tabHost.getTabWidget();
tw.setOrientation(LinearLayout.VERTICAL);
}
Comme TabHost est créé par setContentView, on doit appeler sa méthode de configuration explicitement.
La manière habituelle de créer un onglet est d'appeler:
tabHost.addTab(tabHost.newTabSpec("tab name").setIndicator("title", icon).setContent(...));
La méthode setIndicator, en prenant une chaîne de titre et dessinable en tant que paramètres, crée une mise en page qui est valable uniquement en mode portrait. On doit créer sa propre vue et la donner à setIndicator.Il suffit de copier le TabSpec.LabelAndIconIndicatorStrategy.createIndicatorView code:
private View createIndicatorView(TabHost tabHost, CharSequence label, Drawable icon) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View tabIndicator = inflater.inflate(R.layout.tab_indicator,
tabHost.getTabWidget(), // tab widget is the parent
false); // no inflate params
final TextView tv = (TextView) tabIndicator.findViewById(R.id.title);
tv.setText(label);
final ImageView iconView = (ImageView) tabIndicator.findViewById(R.id.icon);
iconView.setImageDrawable(icon);
return tabIndicator;
}
La différence avec le code Google d'origine est que la mise en page de vue elle-même, la TextView et ImageView ids sont de notre propre application , pas les identifiants internes Android.
Pour le mode portrait, on peut réutiliser les tab_indicator.xml d'Android, que nous stockons dans res/mise en page:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="0dip"
android:layout_height="64dip"
android:layout_weight="1"
android:layout_marginLeft="-3dip"
android:layout_marginRight="-3dip"
android:orientation="vertical"
android:background="@drawable/tab_indicator">
<ImageView android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
/>
<TextView android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
style="?android:attr/tabWidgetStyle"
/>
</RelativeLayout>
Encore une fois, cela est identique à XML Android d'origine, à l'exception des ids. Pour une version compatible paysage, nous devons inverser à nouveau les attributs largeur et hauteur de la mise en page. Ce qui nous donne dans res/mise en terre:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="64dip"
android:layout_height="0dip"
android:layout_weight="1"
android:layout_marginTop="-3dip"
android:layout_marginBottom="-3dip"
android:orientation="vertical"
android:background="@drawable/tab_indicator">
<ImageView android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
/>
<TextView android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
style="?android:attr/tabWidgetStyle"
/>
</RelativeLayout>
(j'ai changé marginLeft et marginRight à marginTop et marginBottom mais ne suis pas sûr qu'il est utile)
Ces derniers fichiers XML de référence @ drawable/tab_indicator , donc nous devons le copier à partir du code source Android, ainsi que drawable/tab_selected.9.png, drawable/tab_unselected.9.png, drawable/tab_focus.9.png.
en train de créer un onglet devient:
tabHost.addTab(tabHost.newTabSpec(AllTabName)
.setIndicator(createIndicatorView(tabHost, "tab title", icon)))
.setContent(this));
EDIT: un projet de démonstration est disponible à l'adresse: VerticalTabHost on SkyDrive
J'ai vraiment essayé d'obtenir des onglets verticaux à travaillez en utilisant tabhost/tabwidget. Je ne l'ai jamais eu à travailler. vous devrez probablement lancer votre propre onglet pour le faire. – Falmarri
Je suis d'accord avec Falmarri. Cela doit être fait dans votre propre disposition personnalisée. TabHost n'est pas très agréable lorsque vous essayez de le personnaliser pour qu'il soit beau à la fois pour le portrait et le paysage. –
Falmarri, Austyn Mahoney, merci pour l'explication. Existe-t-il un moyen réalisable de mettre en place son propre tabwidget? – aiboman