Ecco come ho impostato il TabHost per visualizzare le schede sulla sinistra dello schermo, con le schede sovrapposte verticalmente.
Uno ha bisogno di impostare 2 layout diversi per l'attività, uno in modalità ritratto ("normale"), uno in modalità orizzontale. Ciò implica a non utilizzare TabActivity.
Ho copiato il layout utilizzato da TabActivity nel mio progetto e l'ho chiamato main_view.xml (memorizzato in res/layout). Eccolo:
<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>
Bisogna riutilizzare gli ID Android schede e tabcontent.
Nel panorama, ho cambiato invertendo l'altezza la layout/attributi width per tutti i controlli e modificando l'orientamento del LinearLayout ad orizzontale (la TabWidget e FrameLayout devono essere uno accanto all'altro, in orizzontale). Ecco il risultato, in res/layout terra, chiamato anche 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>
Si noti che se si desidera che le schede sulla destra, si inserisce il TabWidget dopo la FrameLayout in XML sopra.
TabWidget è esso stesso un LinearLayout. Si noti che non ho impostato l'orientamento in XML. Questo perché TabWidget lo fa nel proprio codice (sì, è hardcoded). Per contrastare questo, è necessario reimpostare l'orientamento nel codice. Ecco come ho fatto in
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);
}
Come si crea TabHost attraverso setContentView, si deve chiamare il suo metodo di impostazione OnCreate della mia attività in modo esplicito.
Il solito modo per creare una scheda è di chiamare:
tabHost.addTab(tabHost.newTabSpec("tab name").setIndicator("title", icon).setContent(...));
Il setIndicator metodo, prendendo una stringa titolo e un disegnabile come parametri, crea un layout che è valida solo in modalità verticale. Si deve creare la propria vista e darla a setIndicator.E 'sufficiente copiare il codice TabSpec.LabelAndIconIndicatorStrategy.createIndicatorView:
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 differenza con il codice originale di Google è che il layout di visualizzazione in sé, il TextView e ImageView ID vengono dalla nostra propria applicazione , non gli ID interni di Android.
Per la modalità ritratto, possiamo riutilizzare il tab_indicator.xml da Android, che memorizziamo in res/layout di:
<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>
Ancora una volta, questo è identico al codice XML Android originale, fatta eccezione per gli ID. Per una versione che rispetta l'ambiente, dobbiamo invertire nuovamente gli attributi di larghezza e altezza del layout. Che ci dà in res/layout terra:
<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>
(ho cambiato marginLeft e marginRight a marginTop e MarginBottom, ma non sono così sicuro che sia utile)
Questi ultimi file XML riferimento @ drawable/tab_indicator , quindi abbiamo bisogno di copiarlo dal codice sorgente Android, così come disegnabile/tab_selected.9.png, disegnabile/tab_unselected.9.png, disegnabile/tab_focus.9.png.
Ora la creazione di una scheda diventa:
tabHost.addTab(tabHost.newTabSpec(AllTabName)
.setIndicator(createIndicatorView(tabHost, "tab title", icon)))
.setContent(this));
EDIT: un progetto demo è disponibile all'indirizzo: VerticalTabHost on SkyDrive
realtà ho cercato di ottenere schede verticali lavorare usando il tabhost/tabwidget. Non l'ho mai fatto funzionare. probabilmente dovrai visualizzare la tabulazione per farlo. – Falmarri
Sono d'accordo con Falmarri. Questo deve essere fatto nel tuo layout personalizzato. TabHost non è molto bello quando si cerca di personalizzarlo per avere un bell'aspetto sia verticale che orizzontale. –
Falmarri, Austyn Mahoney, grazie per la spiegazione. C'è un modo fattibile per implementare il proprio tabwidget? – aiboman