Autore Topic: [Facile] Come inserire la ActionBarSherlock in un progetto  (Letto 6413 volte)

Offline GabMarioPower

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 606
  • Respect: +152
    • Github
    • Google+
    • gabrielemariotti
    • GabMarioPower
    • Mostra profilo
  • Play Store ID:
    GAB+MARIO+DEV
  • Sistema operativo:
    Ubuntu 14.04 , Win 10
[Facile] Come inserire la ActionBarSherlock in un progetto
« il: 30 Gennaio 2013, 13:27:16 CET »
+6
Livello di difficoltà: facile
Target SDK: 17
Min SDK: 8
Link al file compresso del progetto eclipse: file in allegato

L'ActionBar è stata introdotta con Android 3.0 (API 11) e al momento in cui scrivo non è stata inserita nella support library. Per questo motivo non possiamo utilizzare il componente su device con un livello di sistema operativo inferiore al 3.0.
Esistono varie alternative per ovviare a questo problema.
Una delle soluzioni migliori, che la stessa Google incoraggia (potete guardare l'app dell'ultimo Google I/O 2012) è utilizzare la libreria ActionBarSherlock di Jake Wharton.

UPDATE MAGGIO 2013:
Google ha rilasciato la ActionBarCompat contenuta nella support-library-v7compat.
Questa soluzione rappresenta una ulteriore alternativa, preferibile anche alla ActionBarSherlock.
-------------------------------------------------------------------------------

La ActionBarSherlock (ABS) è una libreria molto ben scritta, e utilizza l'ActionBar nativa per i dispositivi dove è supportata,e realizza un porting elegante sulle versioni inferiori con il vantaggio di non dover stravolgere il codice.

Per poter utilizzare la libreria, di deve innanzitutto scaricare il file zip che trovate nel sito di riferimento.
Attualmente è disponibile la versione 4.2.0.
Il file zip va unzippato in una cartella in locale.
Personalmente per le librerie utilizzo sempre una cartella esterna rispetto ai workspace di Eclipse, in modo tale che può essere facilmente riutilizzata e condivisa da più workspace.

UPDATE DICEMBRE 2013
Se si vuole lavorare con la ActionBarSherlock con AndroidStudio, non è necessario costruire la libreria in locale, ma  è sufficiente inserire nel build.gradle del progetto questa dipendenza:
Codice (Text): [Seleziona]
dependencies {
    compile 'com.actionbarsherlock:actionbarsherlock:4.4.0@aar'
}
Se sei in questa situazione puoi saltare direttamente nella sezione "Ora il nostro progetto TestAbsLProject è pronto ad utilizzare la ABS"
-------------------------------------------------------------------------------

Il primo passo è importare la libreria all'interno del workspace Eclipse.
L'importazione può essere fatta sia utilizzando la funzione di Import sia creando un nuovo progetto Android da codice esistente. Io preferisco usare la seconda strada.

Open File -> New -> Project -> Android Project From Existing Code.
Utilizzando il wizard l'operazione è semplicissima



Nella videata successiva selezioniamo la cartella dove abbiamo unzippato la libreria e selezioniamo nell'elenco sotto la sola voce library. Vi consiglio di non selezionare l'opzione "Copy projects into workspace"; in questo modo non si crea una copia,e abbiamo un'unica library che può effettivamente essere condivisa da più workspace.



Premendo Finish l'importazione viene completata.
Eclipse visualizzerà un progetto con il nome library all'interno del workspace (che fisicamente risiede sempre all'interno della cartella in cui abbiamo unzippato il file iniziale).
Rinominiamo il progetto all'interno di eclipse in modo tale da poterlo facilmente individuare in futuro, e gli assegnamo il nome di ABS_LIB.

Va subito notato un particolare molto importante.
La nostra nuova libreria utilizza al suo interno la support library di Android; all'interno della cartella libs infatti trovate il file android-support-v4.jar



E' anche importante sottolineare come il progetto ABS_LIB è utilizzato come un library project.(Tasto destro sul progetto ABS_LIB -> Proprietà -> Tab Android )



A questo punto creiamo il nostro progetto vero e proprio all'interno del quale vogliamo utilizzare la ABS (o in alternativa potete utilizzare un progetto già esistente nel quale volete integrare la library).



Chiamerò questo progetto TestAbsProject.
Per inserire la ABS all'interno del progetto, basta cliccare tasto destro sul progetto quindi proprietà.
Selezioniamo il tab Android e scrollando verso il basso troviamo le library utilizzate.
Clicchiamo il pulsante Add, selezioniamo nell'elenco la nostra ABS_LIB.



A questo punto il nostro progetto TestAbsProject è pronto per utilizzare la library ABS.
Prestate attenzione a eventuali messaggi di errore.



Se vi trovate in questa situazione è dovuto al fatto che il vostro progetto sta a sua volta utilizzando la support-library di Android. Come ho specificato sopra, anche ABS_LIB utilizza la support-library di Android.
Questo messaggio semplicemente vi avvisa che i due file android-support-v4.jar sono diversi, e questo determina un errore.

Superare questo errore è molto semplice.
E' sufficiente cancellare il file android-support-v4.jar dal nostro progetto TestAbsProject.
Esplodere il progetto, selezionare la cartella libs e quindi cancellare il file.
In questo modo l'errore precedente scompare.

Attenzione. Apro una piccola parentesi sulla support-library di Android.
Se non siete interessati potete passare direttamente alla parte successiva del template.

La support library di Android è un file che viene (di solito) aggiornato di volta in volta da Google con le nuove API. Questo significa che android-support-v4.jar contenuto nelle API Level 17 non è lo stesso (o potrebbe non esserlo) di quello contenuto nelle API Level 15.
Questo implica che il file andrebbe di volta in volta aggiornata per essere allineati all'ultimo target di API (sempre consigliabile).
Il modo più semplice per farlo, nel nostro scenario,  è copiare l'ultimo file android-support-v4.jar all'interno della cartella libs del progetto ABS_LIB. In questo modo avremmo un progetto pronto per utilizzare l'ultima versione.

Personalmente, preferisco utilizzare uno scenario appena più raffinato, che descrivo brevemente ma non è indispensabile per l'utilizzo della ABS e del nostro template.
Creo un nuovo progetto Android vuoto, copio all'interno della cartella libs il file android-support-v4.jar.
Chiamo il progetto SUPPORT_LIB e lo dichiaro come library project (Tasto destro sul progetto SUPPORT_LIB -> Proprietà -> Tab Android , selezioniamo in basso l'opzione is Library).



A questo punto abbiamo un progetto utilizzabile come library da qualsiasi altro, compresa la ABS_LIB.
Nel progetto ABS_LIB cancelliamo all'interno della cartella libs il file android-support-v4.jar (per evitare di dover ogni volta aggiornare la library) e con il solito tasto destro -> Proprietà -> Tab Android diciamo ad ABS_LIB di utilizzare la library appena creata SUPPORT_LIB.
Abbiamo ottenuto in questo modo di avere nelle nostre library un solo android-support-v4.jar centralizzato che è molto più semplice da aggiornare.

Ora il nostro progetto TestAbsLProject è pronto ad utilizzare la ABS

Utilizziamo una banale Activity.

Codice (Java): [Seleziona]
public class MainActivity extends Activity {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
        }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
                // Inflate the menu; this adds items to the action bar if it is present.
                getMenuInflater().inflate(R.menu.activity_main, menu);
                return true;
        }
}

L'Activity va chiaramente indicata nel Manifest.

Codice (XML): [Seleziona]
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="it.gmariotti.android.examples.testabsproject"
   android:versionCode="1"
   android:versionName="1.0" >

    <uses-sdk
       android:minSdkVersion="8"
       android:targetSdkVersion="17" />

    <application
       android:allowBackup="true"
       android:icon="@drawable/ic_launcher"
       android:label="@string/app_name"
       android:theme="@style/AppTheme" >
        <activity
           android:name="it.gmariotti.android.examples.testabsproject.MainActivity"
           android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Definiamo degli style diversi.
In res/values/styles.xml definiamo:

Codice (XML): [Seleziona]
    <style name="AppBaseTheme" parent="android:Theme.Light"></style>
    <!-- Application theme. -->
    <style name="AppTheme" parent="AppBaseTheme"> </style>

In res/values-v11/styles.xml definiamo:   
Codice (XML): [Seleziona]
     
    <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
        <!-- API 11 theme customizations can go here. -->
    </style>
   
Eseguiamo il nostro progetto.
In un dispositivo con Android 3.0 o superiori abbiamo automaticamente l'ActionBar.
Questo perchè l'ActionBar è abilitata di default in qualsiasi Activity che utilizza uno tema Thema.Holo e ha un target minimo di SDK al livello 11.
Nel dispositivo con Android inferiore a 3.0 non appare nessuna ActionBar.

Per poter sfruttare la nostra ABS, dobbiamo apportare alcune modifiche semplici al nostro codice.

Innanzitutto dobbiamo modificare la dichiarazione della classe ed estendere SherlockActivity invece di Activity.

Codice (Java): [Seleziona]
        public class MainActivity extends SherlockActivity {
          ....
         
Notere subito che il metodo public boolean onCreateOptionsMenu(Menu menu)   presenta degli errori di compilazione. L'errore è "Cannot override the final method from SherlockActivity".

Per capire il perchè di questo errore è sufficiente aprire il sorgente di SherlockActivity.
La ABS sovrascrive tutti i metodi che utilizzano Menu, MenuItem e MenuInflater dell'Activity da cui (ovviamente) deriva e li dichiara come final.
Perchè sovrascrive questi metodi? La risposta è nel meccanismo stessa della ABS.
L'ABS utilizza l'ActionBar nativa nei dispositivi che la supportano, mentre in quelli precedenti effettua un porting che trasforma tutti gli item presenti nel menù in menu items della actionbar, uniformando il comportamento dei dispositivi.

Di primo acchito si potrebbe pensare che questo comporterà una dura riscrittura del nostro codice.
Dal mio punto di vista, le modifiche sono semplici poichè la stessa SherlockActivity espone gli stessi metodi con lo stesso nome e lo stesso numero di argomenti. L'unica cosa che cambia è il package delle classi utilizzate.
   
La prima cosa da effettuare è cancellare gli import di tutte le classi relative a Menu, MenuItem e MenuInflater. Il package attuale è quello standard android.view.
Il package che verrà proposto e andrà scelto è : com.actionbarsherlock.view.



Noterete ora un ulteriore errore di compilazione nel codice getMenuInflater().inflate(R.menu.activity_main, menu);. L'errore di compilazione è The method inflate(int, Menu) in the type MenuInflater is not applicable for the arguments (int, Menu).

E' sufficiente modificare la riga
   
Codice (Java): [Seleziona]
getMenuInflater().inflate(R.menu.activity_main, menu);in
   
Codice (Java): [Seleziona]
getSupportMenuInflater().inflate(R.menu.activity_main, menu);
Il nostro codice finale diventa:

Codice (Java): [Seleziona]
public class MainActivity extends SherlockActivity {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
        }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
                // Inflate the menu; this adds items to the action bar if it is present.
                getSupportMenuInflater().inflate(R.menu.activity_main, menu);
                return true;
        }
}
Allo stesso modo dobbiamo cambiare eventuali chiamate alla ActionBar.
Per esempio:
   
Codice (Java): [Seleziona]
getActionBar().setHomeButtonEnabled(false);diventa:
   
Codice (Java): [Seleziona]
getSupportActionBar().setHomeButtonEnabled(false);
Il nostro progetto non è ancora pronto.
Se guardiamo la documentazione della ABS Temi della ABS troviamo che per utilizzare la libraria dobbiamo apportare alcune modifiche allo stile.
In particolare dobbiamo utilizzare (must) uno dei temi Theme.Sherlock, Theme.Sherlock.Light, o Theme.Sherlock.Light.DarkActionBar.

Possiamo utilizzare direttamente uno di questi temi, oppure utilizzare un proprio tema che viene esteso da quelli della ABS.

Modifichiamo il nostro res/values/styles.xml in
   
Codice (XML): [Seleziona]
    <style name="AppBaseTheme" parent="Theme.Sherlock.Light"></style>

    <!-- Application theme. -->
    <style name="AppTheme" parent="AppBaseTheme"> </style>
       
A questo punto il nostro progetto è funzionante.   
Per completezza riporto il file res/menu/activity_main.xml che utilizziamo per popolare il menu e l'action bar.
Codice (XML): [Seleziona]
        <menu xmlns:android="http://schemas.android.com/apk/res/android" >
                <item
                        android:id="@+id/update_item"
                        android:icon="@drawable/ic_action_refresh"
                        android:showAsAction="ifRoom"
                        android:title="@string/menu_refresh"
                        android:titleCondensed="@string/menu_refresh">
                </item>
               
                <item
                        android:id="@+id/menu_settings"
                        android:orderInCategory="100"
                        android:showAsAction="never"
                        android:title="@string/menu_settings"/>
        </menu>
       
Se lo eseguiamo sullo stesso dispositivo con Android superiore a 3.0 avremmo lo stesso comportamento di prima, senza alcuna modifica.
Nei dispositivi con una versione di Android inferiore a 3.0 invece avremmo finalmente una visualizzazione quasi identica con una Action Bar.
Qui sotto potete trovare le due visualizzazioni, la prima in un dispositivo 2.3, la seconda in un dispositivo 4.2.1




   

L'unica differenza fra le due visualizzazioni è l'overflow-menu (i tre puntini verticali). In base alle attuali specifiche Android il menu overflow compare solo nei device che non hanno il pulsante menu.

A questo punto abbiamo realizzato un progetto che utilizza l'ActionBar indipendentemente dal livello di sistema operativo Android.
Per ulteriori utilizzi, si può far riferimento alla normale documentazione della Action Bar.
L'unica osservazione che aggiungo, è quella di ricordarsi di utilizzare sempre risorse (icone) definite all'interno del progetto.
Come la stessa Google ci invita a fare, non utilizziamo icone del pacchetto standard, ma copiamole e utilizziamole all'interno del nostro progetto.

I sorgenti del progetto TestAbsProject li trovate nel file allegato, oppure su GitHub TestAbsProject

Bibliografia:
« Ultima modifica: 06 Dicembre 2013, 16:20:33 CET da GabMarioPower »

Offline GabMarioPower

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 606
  • Respect: +152
    • Github
    • Google+
    • gabrielemariotti
    • GabMarioPower
    • Mostra profilo
  • Play Store ID:
    GAB+MARIO+DEV
  • Sistema operativo:
    Ubuntu 14.04 , Win 10
Re: [Facile] Come inserire la ActionBarSherlock in un progetto
« Risposta #1 il: 30 Gennaio 2013, 17:31:07 CET »
0
Ho dimenticato, per completezza, di dire che la libreria non si limita alla sola SherlockActivity, ma copre anche gli componenti interessati:
SherlockListActivity, SherlockFragment, SherlockListFragmentList , SherlockDialogFragment e SherlockPreferenceActivity.

Per chi invece si è imbattuto (argomento decisamente più vasto e complesso) nell'utilizzo delle nuove Google Maps v2 la library ufficiale non basta.
Esiste però una rivisitazione funzionale allo scopo qui:
SherlockMapFragment

Offline GennyAndroid

  • Utente junior
  • **
  • Post: 115
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy Ace
  • Play Store ID:
    Gennaro Petito
  • Sistema operativo:
    Windows 7
Re: [Facile] Come inserire la ActionBarSherlock in un progetto
« Risposta #2 il: 31 Gennaio 2013, 01:06:56 CET »
0
Veramente ben fatta, non appena avrò tempo la metterò in pratica, grazie

Offline lionell88

  • Utente junior
  • **
  • Post: 56
  • Respect: 0
    • Mostra profilo
Re: [Facile] Come inserire la ActionBarSherlock in un progetto
« Risposta #3 il: 11 Aprile 2013, 17:15:33 CEST »
0
Bella guida...
Una domanda. Se volessi utilizzare anche la classe FragmentActivity per fare uno swipe layout stile market di Android? Non posso mica estendere due classi. Come potrei fare? Grazie infinite.

Offline Sakazaki

  • Utente normale
  • ***
  • Post: 396
  • Respect: +74
    • Mostra profilo
  • Dispositivo Android:
    Sony xperia Z
  • Play Store ID:
    Saka Labs
  • Sistema operativo:
    Windows 8
Re: [Facile] Come inserire la ActionBarSherlock in un progetto
« Risposta #4 il: 11 Aprile 2013, 17:39:10 CEST »
0
Bella guida...
Una domanda. Se volessi utilizzare anche la classe FragmentActivity per fare uno swipe layout stile market di Android? Non posso mica estendere due classi. Come potrei fare? Grazie infinite.

Ci sono le classi SherlockFragmentActivity e SherlockFragment, nella directory samples del pacchetto ActionBarSherlock c'è un'esempio che illustra come usarle.

Offline lionell88

  • Utente junior
  • **
  • Post: 56
  • Respect: 0
    • Mostra profilo
Re: [Facile] Come inserire la ActionBarSherlock in un progetto
« Risposta #5 il: 11 Aprile 2013, 17:43:34 CEST »
0
Si, stavo per scriverlo. Ho esteso SherlockFragmentActivity anzicché FragmentActivity ed ora funziona pure l'action bar :)

Offline lionell88

  • Utente junior
  • **
  • Post: 56
  • Respect: 0
    • Mostra profilo
Re: [Facile] Come inserire la ActionBarSherlock in un progetto
« Risposta #6 il: 14 Aprile 2013, 12:13:56 CEST »
0
Ragazzi ancora una domanda: come si potrebbe fare per aggiungere uno spinner all' action bar? 

Offline MisterHide

  • Utente junior
  • **
  • Post: 65
  • Respect: 0
    • Mostra profilo
  • Sistema operativo:
    Windows XP
Re: [Facile] Come inserire la ActionBarSherlock in un progetto
« Risposta #7 il: 15 Aprile 2013, 11:18:54 CEST »
0
lionell88, x aggiungere lo spinner io ho fatto così:

Codice: [Seleziona]
Context context = getSupportActionBar().getThemedContext();
ArrayAdapter<String> list = new ArrayAdapter<String>(context, R.layout.sherlock_spinner_item,Citta);
list.setDropDownViewResource(R.layout.sherlock_spinner_dropdown_item);
actionBar=getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
actionBar.setListNavigationCallbacks(list, this);


Offline lionell88

  • Utente junior
  • **
  • Post: 56
  • Respect: 0
    • Mostra profilo
Re: [Facile] Come inserire la ActionBarSherlock in un progetto
« Risposta #8 il: 15 Aprile 2013, 12:18:44 CEST »
0
Grazie. Purtroppo però non mi viene visualizzata la mia lista. Lo spinner non si espande :( ... Al posto di Citta ho messo il mio array così
Codice (Java): [Seleziona]
R.array.drop_down_spinner

Post unito: 15 Aprile 2013, 12:42:02 CEST
In realtà, credo che sia opportuno usare SpinnerAdapter. Ho fatto così
Codice (Java): [Seleziona]
        SpinnerAdapter mSpinnerAdapter = ArrayAdapter.createFromResource(this,
            R.array.drop_down_spinner,
            R.layout.sherlock_spinner_dropdown_item);
        ActionBar actionBar=getSupportActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
       
        actionBar.setListNavigationCallbacks(mSpinnerAdapter, new OnNavigationListener() {
                @Override
                public boolean onNavigationItemSelected(int itemPosition, long itemId) {
                         
             
                        return false;
                }
               
        });

Ora funziona ;)
« Ultima modifica: 15 Aprile 2013, 12:46:14 CEST da lionell88 »

Offline MisterHide

  • Utente junior
  • **
  • Post: 65
  • Respect: 0
    • Mostra profilo
  • Sistema operativo:
    Windows XP
Re: [Facile] Come inserire la ActionBarSherlock in un progetto
« Risposta #9 il: 15 Aprile 2013, 12:47:19 CEST »
0
Strano a me funziona benissimo e l'ho implementato proprio stamattina   :-o
comunque l'importante è che ora ti funziona ;-)

ciao.

Offline lionell88

  • Utente junior
  • **
  • Post: 56
  • Respect: 0
    • Mostra profilo
Re: [Facile] Come inserire la ActionBarSherlock in un progetto
« Risposta #10 il: 15 Aprile 2013, 12:52:36 CEST »
0
Giusto per curiosità, nel tuo codice, dove prendi le stringhe da visualizzare nello spinner?

Offline MisterHide

  • Utente junior
  • **
  • Post: 65
  • Respect: 0
    • Mostra profilo
  • Sistema operativo:
    Windows XP
Re: [Facile] Come inserire la ActionBarSherlock in un progetto
« Risposta #11 il: 15 Aprile 2013, 15:09:19 CEST »
0
ho un Array Citta, così giusto per provare avevo messo:

Codice: [Seleziona]
private String[] Citta={"Roma","Torino","Firenze","Milano","Napoli"};

Offline lionell88

  • Utente junior
  • **
  • Post: 56
  • Respect: 0
    • Mostra profilo
Re: [Facile] Come inserire la ActionBarSherlock in un progetto
« Risposta #12 il: 18 Aprile 2013, 16:26:27 CEST »
0
Ho notato un errore. Seguendo questa guida alla perfezione, sul logCat vedo: "Style contains key with bad entry: 0x01000000" .
Ora, su Android 2.3.3, l'app gira comunque (nonostante l'errore); su Android 4 crasha.
Cosa potrebbe essere?

Offline Ormet

  • Utente junior
  • **
  • Post: 71
  • Respect: 0
    • Google+
    • Marco Falotico
    • Mostra profilo
  • Dispositivo Android:
    HTC One S
  • Play Store ID:
    Ormet
  • Sistema operativo:
    Windows 7
Re: [Facile] Come inserire la ActionBarSherlock in un progetto
« Risposta #13 il: 02 Giugno 2013, 12:52:51 CEST »
0
A me non carica la libreria..come mai?ho seguito tutto alla lettera e mi dice "Android Library Project cannot be launched"..  ??? :-(

Ho sistemato da solo..non so il motivo ma non importava tutta la libreria..cancellata, reimportata e funziona..GRAZIE MILLE DEL TUTORIAL
« Ultima modifica: 02 Giugno 2013, 13:30:51 CEST da Ormet »