Autore Topic: [Medio] Personalizzare il colore di sfondo di un TabWidget  (Letto 3683 volte)

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3489
  • Respect: +507
    • Github
    • Google+
    • rciovati
    • Mostra profilo
[Medio] Personalizzare il colore di sfondo di un TabWidget
« il: 01 Settembre 2010, 21:13:02 CEST »
+6
Livello di difficoltà: medio
Versione SDK utilizzata: testata su 1.5 e 2.2
Link al file compresso del progetto eclipse: file in allegato

In questo tutorial vi presento una possibile soluzione per personalizzare il colore di sfondo di un tabwidget.
Parlo di "possibile soluzione" perchè queto è difatto un work-around poichè non vi è una vera e propria api per personalizzare questo widget.



Una tab di un TabWidget è costituita da due componenti:
-Indicator: è sostanzialmente "l'etichetta" della tab, la view dove vi è il titolo ed eventualmente l'icona
-Content: è il contentuto della tab, che può essere una view o un'activity

Quello che andremo noi a fare è personalizzare il background dell'Indicator.

Iniziamo vedendo il codice principale del'activity TabExample, che è l'unica del progetto:
Codice (Java): [Seleziona]
        @Override
        public void onCreate ( Bundle savedInstanceState ) {
                super.onCreate( savedInstanceState );
                setContentView( R.layout.main );

                //Inizializzazione
                // Otteniamo il riferimento al TabHost
                TabHost tabHost = ( TabHost ) findViewById( R.id.myTabHost );
                tabHost.setup();
                // Aggiungiamo il Tab associato alla prima view
                tabHost.addTab( tabHost.newTabSpec( "tabview1" ).setContent( R.id.tabview1 ).setIndicator( "Prima" ) );
                // Aggiungiamo il Tab associato alla seconda view
                tabHost.addTab( tabHost.newTabSpec( "tabview2" ).setContent( R.id.tabview2 ).setIndicator( "Seconda" ) );
                // Aggiungiamo il Tab associato alla terza view
                tabHost.addTab( tabHost.newTabSpec( "tabview3" ).setContent( R.id.tabview3 ).setIndicator( "Terza" ) );

               
                TabWidget tw = tabHost.getTabWidget();
               
                //Qui sotto è la parte dove viene assegnato il nuovo drawable che imposta il colore di sfondo
                for ( int i = 0; i < tw.getChildCount(); i++ ) {
                        View v = tw.getChildAt( i );
                       
                        //La view che rappresenta la tab vera e propria è un RelativeLayout
                        if ( v instanceof RelativeLayout )
                                v.setBackgroundDrawable( getResources().getDrawable( R.drawable.tab_indicator ) );
                }
                //Rimuoviamo lo strip di default
                removeBottomStrip( tw );
        }

La classe TabExample contiene sostanzialmente il code per inizializzare le tab, per personalizzarne il background e per rimuovere il divider (chiamato strip, vedi immagine sotto). La personalizzazione consiste nell'assegnare alle view un Drawable che rappresenta il colore di sfondo.


Il drawable utilizzato ha lo scopo di definire che gradiente deve venir utilizzato in base allo stato in cui si trova la tab.
Gli stati possibili che una tab (e una qualsiasi view in Android) può assumere sono: focused, pressed e selected. Per un approfondimento sul significato di questi stati vi invito a fare riferimento alla documentazione. Vediamo ora il file:
La definizione vera e propria dei gradienti per chiarezza viene fatta in file separati, li potete trovare nel progetto allegato.

Ecco il codice del file tab_indicator.xml
Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Non focused states -->
    <item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/tab_unselected" />
    <item android:state_focused="false" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/tab_selected" />

    <!-- Focused states -->
    <item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/tab_focus" />
    <item android:state_focused="true" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/tab_focus" />

    <!-- Pressed -->
    <item android:state_pressed="true" android:drawable="@drawable/tab_press" />
</selector>

Questo file è uguale a quello che utilizza di default android. (vedi http://tinyurl.com/3x3twa9)

Ho pensato poi di inserire un piccolo strip  una View alta 4dip con impostato un colore di background corrispondente al quello della tab premuta.
La rimozione dello strip di default non è proprio semplice perchè i metodi per manipolarlo sono stati introdotti a partire dall'API level 4 (Android 1.6) percui ho dovuto utilizzare la reflection (vedi il metodo removeBottomStrip) per poter far funzionare il codice anche su Android 1.5.

Questo lavoro rappresenta un work in progress. Vorrei infatti inserire una spaziatura tra le tab. In un altro esperimento sono riuscito ad ottenere questo risultato usando come indicator una View custom ma (come sempre) non funziona sull'Api Level 3.



Offline -Bruno90-

  • Nuovo arrivato
  • *
  • Post: 41
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    HTC wildfire
  • Sistema operativo:
    Windows XP
Re:[Medio] Personalizzare il colore di sfondo di un TabWidget
« Risposta #1 il: 08 Novembre 2010, 15:41:31 CET »
0
Ciao a tutti
Innanzitutto grazie per l'ottimo tutorial!!
Però ho un problema che non riesco a risolvere:
Con la  funzione
 
Codice (Java): [Seleziona]
tabHost.addTab( tabHost.newTabSpec( "tabview1" ).setContent( R.id.tabview1 ).setIndicator( "Prima" ) );io vorrei aggiungere un tab che faccia partire un'altra activity che poi farà delle operazioni.
Seguendo il tutorial: tabHost.addTab( tabHost.newTabSpec( "tabview1" ).setContent( R.id.tabview1 ).setIndicator( "Prima" ) ); non sono riuscito ad ottenere quello che volevo in quanto nell'activity chiamata mette solo una textview. Il mio dubbio è qua: Posso importare una altro file .xml di layout che poi verrà visualizzato sotto i tab??
io ho provato sostituendo con
Codice (Java): [Seleziona]
Intent intent = new Intent().setClass(this, Tab1.class);
spec = tabHost.newTabSpec("tabview2").setIndicator("Tab1")
            .setContent(intent);
Dove nella classe Tab1 ho importato un altro file xml
quando eseguo il logcat stampa:
E/AndroidRuntime( 6681): java.lang.IllegalStateException: Did you forget to call
 'public void setup(LocalActivityManager activityGroup)'?
E/AndroidRuntime( 6681):        at android.widget.TabHost$IntentContentStrategy.
getContentView(TabHost.java:646)
E/AndroidRuntime( 6681):        at android.widget.TabHost.setCurrentTab(TabHost.
java:320)
E/AndroidRuntime( 6681):        at android.widget.TabHost$2.onTabSelectionChange
d(TabHost.java:129)
E/AndroidRuntime( 6681):        at android.widget.TabWidget$TabClickListener.onC
lick(TabWidget.java:379)

Come potrei fare??? e soprattutto, è possibile una cosa del genere??
Grazie in anticipo.

Offline -Bruno90-

  • Nuovo arrivato
  • *
  • Post: 41
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    HTC wildfire
  • Sistema operativo:
    Windows XP
Re:[Medio] Personalizzare il colore di sfondo di un TabWidget
« Risposta #2 il: 08 Novembre 2010, 15:42:50 CET »
0
scusate il  tutoria che ho seguito è qui:
http://developer.android.com/resources/tutorials/views/hello-tabwidget.html
Dannati copia e incolla!!
 :D

Offline mambu

  • Utente normale
  • ***
  • Post: 167
  • Respect: +1
    • Mostra profilo
  • Sistema operativo:
    Windows 7
Re:[Medio] Personalizzare il colore di sfondo di un TabWidget
« Risposta #3 il: 01 Febbraio 2012, 16:42:20 CET »
0
ciao, ero interessato a realizzare una tabhost un po più dettagliata, molto più ispirata alla tua seconda foto. Come potrei fare?

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3489
  • Respect: +507
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:[Medio] Personalizzare il colore di sfondo di un TabWidget
« Risposta #4 il: 01 Febbraio 2012, 16:44:09 CET »
0
ciao, ero interessato a realizzare una tabhost un po più dettagliata, molto più ispirata alla tua seconda foto. Come potrei fare?

è un normalissimo TabWidget, puoi usare una TabActivity, dovresti trovare molti tutorial a riguardo.

Offline mambu

  • Utente normale
  • ***
  • Post: 167
  • Respect: +1
    • Mostra profilo
  • Sistema operativo:
    Windows 7
Re:[Medio] Personalizzare il colore di sfondo di un TabWidget
« Risposta #5 il: 01 Febbraio 2012, 16:51:41 CET »
0
Onestamente di fatte così non trovo molti tutorial

ne trovo molti come il tuo in cui la tab non è altro che un rettangolo colorato