Livello di difficoltà: facile.
Versione target SDK utilizzata: 19.
Versione minima SDK: 8.
In questo tutorial spiegherò come realizzare una ListView con un adattatore personalizzato, in base alle proprie esigenze. Per questa guida l'adapter sarà composto semplicemente da una ImageView e due TextView. Iniziamo!
Per prima cosa è necessario creare il layout collegato all'activity principale, che avrà come unico elemento una semplice ListView. Andiamo quindi in /res/layout/ apriamo il file activity_main.xml e inseriamo al suo interno:
1
2<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3xmlns:tools="http://schemas.android.com/tools"
4android:layout_width="fill_parent"
5android:layout_height="fill_parent"
6tools:context=".MainActivity" >
7
8<ListView
9android:id="@+id/listView1"
10android:layout_width="fill_parent"
11android:layout_height="fill_parent"
12>
13
14</ListView>
15
16</RelativeLayout>
17
Quindi rechiamoci nell'Activity principale in /src/ e apriamo MainActivity.java. Inseriamo:
321
2public class MainActivity extends Activity {
3
4String[] testi, sottoTesti;
5Adapter adapter;
6ListView lista;
7
8
9protected void onCreate(Bundle savedInstanceState) {
10super.onCreate(savedInstanceState);
11setContentView(R.layout.activity_main);
12
13lista = (ListView)findViewById(R.id.listView1);
14lista.setFastScrollEnabled(true);
15testi = new String[] {"Prova", "Prova, "Prova"};
16
17sottoTesti = new String[] {"Sub", "Sub", "Sub"};
18adapter = new Adapter(this, testi, sottoTesti);
19lista.setAdapter(adapter);
20
21lista.setOnItemClickListener(new OnItemClickListener() {
22
23
24public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
25// TODO Auto-generated method stub
26Toast.makeText(getBaseContext(), "Hai cliccato "+arg2+" con id "+arg3, Toast.LENGTH_SHORT).show();
27}
28
29});
30}
31}
32
Le prime tre righe di codice prevedono la dichiarazione di due array di stringhe (String[]), l'Adapter (che creeremo tra poco) e la ListView. Per creare l'Adapter torniamo nuovamente in /res/layout/ e creiamo un nuovo file che chiameremo adapter.xml. Inseriamo:
331
2
3<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
4android:layout_width="match_parent"
5android:layout_height="match_parent" >
6
7<TextView
8android:id="@+id/textView1"
9android:layout_width="wrap_content"
10android:layout_height="wrap_content"
11android:layout_alignParentTop="true"
12android:layout_toRightOf="@+id/imageView"
13android:textStyle="bold"
14/>
15
16<TextView
17android:id="@+id/textView2"
18android:layout_width="wrap_content"
19android:layout_height="wrap_content"
20android:layout_below="@+id/textView1"
21android:layout_toRightOf="@+id/imageView"
22android:textStyle="italic"
23/>
24
25<ImageView
26android:id="@+id/imageView"
27android:layout_width="50dip"
28android:layout_height="50dip"
29android:layout_alignParentLeft="true"
30android:src="@drawable/ic_launcher"
31/>
32
33</RelativeLayout>
Quindi, di nuovo in /src/ creiamo una classe che chiamiamo Adapter.java, nella quale inseriremo:
351public class Adapter extends ArrayAdapter<String>{
2
3String[] testo, sottoTesto;
4Context context;
5Holder holder;
6
7public Adapter(Context context, String[] testo, String[] sottoTesto) {
8super(context, R.layout.adapter, testo);
9// TODO Auto-generated constructor stub
10this.testo = testo;
11this.sottoTesto = sottoTesto;
12this.context = context;
13}
14
15public View getView(int position, View view, ViewGroup parent) {
16if(view == null) {
17holder = new Holder();
18LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
19view = inflater.inflate(R.layout.adapter, null, true);
20holder.textView = (TextView)view.findViewById(R.id.textView1);
21holder.textView2 = (TextView)view.findViewById(R.id.textView2);
22holder.textView.setText(testo[position]);
23holder.textView2.setText(sottoTesto[position]);
24view.setTag(holder);
25}
26else {
27holder = (Holder)view.getTag();
28}
29return view;
30}
31}
32
33class Holder {
34TextView textView, textView2;
35}
Come vedete il costruttore prevede tre parametri: il contesto, l'array di stringhe dei testi e dei sotto-testi. Il metodo getView() è molto importante. Esso si occupa della gestione del singolo elemento dalla lista. I parametri al suo interno sono: la posizione, view e parent. Soffermiamoci su questi ultimi due: il parametro view, se opportunamente ottimizzato ci permette di rendere la lista molto fluida nello scroll ed evitare quindi i fastidiosi lag dovuti, appunto, alla mancata ottimizzazione. In maniera spicciola, view ci consente di riciclare l'eventuale View che anzichè essere "rigenerata" viene riciclata, ragion per cui viene fatto il controllo. Se è nulla, tramite l'operazione di Inflating la creiamo, altrimenti la ricicliamo. Il parametro parent è il contenitore avente il compito di raccogliere gli elementi generati dal metodo getView(). Generalmente è la ListView stessa. L'oggetto Holder consente di memorizzare il riferimento alle View in ogni singola riga della lista. Tramite il metodo setTag() associamo l'oggetto Holder alla View, per poi riottenerlo col getTag(). Questi piccoli accorgimenti nel complesso rendono la lista efficiente, evitando sprechi di risorse, di memoria, oltre che evitano il presentarsi di lag/impuntamenti.
Questo è tutto. Per ulteriori chiarimenti potete scrivere in questa discussione. Un ringraziamento speciale all'utente supertommino.