Durante lo sviluppo di un’applicazione Android, uno degli aspetti cui è necessario far caso è la manipolazione dinamica del layout tramite codice Java includendo sia la gestione dei dati che degli eventi. Per fare ciò, è necessario familiarizzare con due elementi:
- il metodo findViewById che recupera il riferimento ad una View in base all’id assegnatole;
- i listener, oggetti tramite i quali la nostra app organizza la sua reazione agli eventi.
Tutto ciò richiede molto codice, a volte ripetitivo, la cui quantità spesso mina la produttività dello sviluppatore. In questo tutorial, vediamo pertanto un possibile antidoto che prende la forma di una libreria piccola, ma ricca di funzionalità: ButterKnife.
ButterKnife: integrazione e tratti principali
Questo strumento deve prima di tutto essere incluso all’interno del nostro progetto Android Studio, operazione che grazie a Gradle risulta piuttosto agevole. Inseriamo il seguente elemento nel blocco dependencies del file build.gradle asservito al nostro modulo di progetto:
compile 'com.jakewharton:butterknife:8.0.1'
La versione 8.0.1, come si presume, è la più recente al momento della stesura del tutorial: andrà poi sostituita con quella opportuna in fase di utilizzo.
Dopo la modifica il progetto deve essere sincronizzato con i file build.gradle tramite la pressione dell’apposito pulsante .
ButterKnife viene utilizzato tramite annotazioni in base alle quali sarà prodotto del codice senza ricorrere alla costosa (in termini di prestazioni) Reflection di Java.
L’esempio
L’esempio che segue illustra l’utilizzo delle libreria tramite un semplice layout:
E’ composto da tre elementi: una EditText, un Button ed una ListView. Al click del pulsante “Salva” il testo scritto nella EditText – a patto non sia vuota – viene accodato all’Adapter che alimenta la ListView. Inoltre, al click di un item della Listview apparirà un Toast che dichiara quale elemento è stato selezionato:
L’esempio è piuttosto immediato in quanto non ha altra finalità se non quella di mostrare come ButterKnife può semplificare la vita dello sviluppatore.
Il codice
Vediamo subito il layout (per noi è il file /res/layout/activity_main.xml):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="@dimen/activity_horizontal_margin"> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/txt" android:layout_alignParentTop="true"/> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/save" android:layout_below="@id/txt" android:text="Salva"/> <ListView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/save" android:id="@+id/list" android:layout_marginTop="10dp"/> </RelativeLayout>
Ricordiamo anche che abbiamo definito una risorsa stringa, nel file /res/values/strings.xml, di nome msg:
<resources> <string name="app_name">ButterKnife</string> <string name="msg">Elemento cliccato:</string> </resources>
Nel codice Java che vedremo, ButterKnife fornirà i seguenti contributi:
- con l’annotazione @Bind ci permetterà di recuperare in automatico una View e collegarla ad un membro della classe senza il ricorso al metodo findViewByID, ma semplicemente indicando l’id del widget che ci interessa
@Bind(R.id.txt) EditText txt;
- con @BindString avremo istantaneamente il valore di una risorsa stringa in un membro String:
@BindString(R.string.msg) String msg;
Esiste un omologo per ogni altro tipo di risorse valore;
- i listener saranno gestiti con dei semplici metodi e l’annotazione premessa specificherà evento e widget cui sono collegati. Questo, ad esempio, è il click sul pulsante:
@OnClick(R.id.save) public void submit() { // codice da eseguire }
mentre quest’altro è l’organizzazione di un evento di click sull’item di una ListView:
@OnItemClick(R.id.list) void onItemSelected(int position) { // codice da eseguire }
Chi è abituato alla solita sintassi delle Activity Android riconoscerà subito i benefici di questa libreria. Ecco il codice completo dell’Activity:
public class MainActivity extends AppCompatActivity { @Bind(R.id.txt) EditText txt; @Bind(R.id.list) ListView list; @BindString(R.string.msg) String msg; private ArrayAdapter<String> adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); adapter=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1); list.setAdapter(adapter); } @OnClick(R.id.save) public void submit() { String t=txt.getText().toString(); if (t.length()>0) { adapter.add(t); txt.setText(""); } } @OnItemClick(R.id.list) void onItemSelected(int position) { Toast.makeText(MainActivity.this, msg+adapter.getItem(position), Toast.LENGTH_SHORT).show(); } }
Fondamentale notare che tutto ciò che ha innescato il funzionamento di ButterKnife è la chiamata al metodo statico bind nell’onCreate:
ButterKnife.bind(this);
Ulteriori aspetti
Quello che abbiamo visto ha già molti vantaggi, ma non è che una parte di tutto ciò che ButterKnife mette a disposizione: sul sito del progetto si possono trovare molti altri spunti.
Uno dei principali vantaggi di ButterKnife è l’immediatezza con cui la si inizia ad usare tanto che potremmo considerarla una versione “soft” di progetti molto più corposi e complessi come Dagger, libreria ormai patrocinata da Google, ma creata da Square Inc., l’azienda che dà lavoro a Jake Wharton, il creatore di ButterKnife.
Che si riferisca proprio a questo la frase riportata sulla pagina GitHub del progetto “Remember: A butter knife is like a dagger only infinitely less sharp.” ossia “Ricorda: un coltello da burro è come un pugnale solo infinitamente meno tagliente” ?
No Responses to “ButterKnife: Field and method binding for Android views”