Um eine Liste von Einträgen anzeigen zu lassen, bietet Android die Möglichkeit der ListActivity. Eine einfache ListActivity mit einer statischen Menge von Einträgen ist schnell implementiert; eine komplexe ListActivity mit eigenem ListAdapter und Performanceproblemen leider auch.
public class SimpleStaticListActivity extends ListActivity {
// ...
private static String[] listEntries = new String[] {"1. Eintrag", "2. Eintrag", "3. Eintrag", "4. Eintrag"};
public void onCreate() {
super.onCreate(savedInstanceState);
// dein Layout
setContentView(R.layout.simpleStaticList);
// der List-Adapter
setListAdapter(new ArrayAdapter(this, R.id.TextView01, listEntries));
}
}
Dies wir aber nur selten der Fall sein und auch in diesem Beispiel benutzen wir bereits einen ArrayAdapter, der die Methode getView implementiert und sich entsprechend performant um die Darstellung kümmert. In den meisten Fällen werden die Daten aus einer Datenbank stammen oder von einer anderen Datenquelle, die einen Cursor bereitstellt. Für diese Eventualität stellt Android den SimpleCursorAdapter bereit; dieser Adapter mappt eine Menge von Columns (der Datenquelle) auf eine Menge von Ids von Views.
public class SimpleCursorAdapterListActivity extends ListActivity {
// ...
public void onCreate() {
super.onCreate(savedInstanceState);
// dein Layout
setContentView(R.layout.simpleStaticList);
// dbHelper ^= Facade zur Datenbank
Cursor entries = dbHelper.getEntries();
// Wichtig: Android kümmert sich um den Lifecycle des Cursors
startManagingCursor(entries);
SimpleCursorAdapter entryAdapter = new SimpleCursorAdapter(this, R.layout.row, entries, new String[] {"_id"}, new int[] {R.id.TextView01});
setListAdapter(entryAdapter);
}
}
Okay nun haben wir eine einfache Liste mit einer Menge von Einträgen, die immer gleich aussehen. Meist reicht dies schon. Will man jetzt mehr Einfluss haben, dann muss man einen eigenen ListAdapter entwickeln und die getView – Methode implementieren. Hier ist aber Vorsicht geboten. getView wird häufiger aufgerufen, als man sich vielleicht vorstellen kann. Auf der Developer Conference hat Romain Guy einen Vortrag über „Turbo-charge your UI: How to Make your Android UI Fast and Efficient“ gehalten und ist genau auf diesen Punkt eingegangen. Die wichtigsten Punkte sind:
- Erzeuge keine Objekte in der Methode, wenn es nicht wirklich notwendig ist
- Wiederverwende das View-Element, welches als zweiter Parameter übergeben wird und setze die relevanten Werte
Ich will hier kurz einmal die schlechteste Implementierung anreißen; wenn ihr Performanceprobleme habt und eure Implementierung ähnelt dem folgenden Beispiel, dann habt ihr noch ein wenig Arbeit vor euch.
public class SlowCursorAdapter implements ListAdapter {
// ...
public View getView(int position, View convertView, Viewgroup parent) {
// mInflater ^= android.view.LayoutInflater
View view = mInflater.inflate(R.layout.listItem, null);
((TextView) view.findItemById(R.id.textView01)).setText(position + " Eintrag");
return view;
}
Es wird bei diesem Code entweder zu der Fehlermeldung kommen, dass die Anwendung nicht mehr reagiert oder beim Scrollen wird die Anwendung hängen bleiben da der Garbage Collector die alten View ständig weglöschen muss. Romain Guy gibt an, dass alleine die erste Zeile 50ms Rechenzeit in Anspruch nimmt (auf seinem Google G1).
Ihr werdet sehr oft merken, dass eine Handy-CPU nicht so schnell ist, wie ein Desktop-PC (auch wenn man das eigentlich schon vorher wissen sollte) und eure „Programmlogiken“ in Tasks auslagern; mein erster Berührungspunkt mit Tasks kam sehr schnell, da ich in meiner ersten App eine Gallery mit Fotos anzeigen lassen wollte und man nicht die Originalfotos einfach nehmen kann und die Thumbnails einem auch nicht bereitgestellt werden.
Es gibt also keine Geheimnisse in Android, aber man muss teilweise lange Suchen, um die richtigen Antworten zu finden, da die API – Dokumentation doch recht wortkarg ist (z.B. MediaStore.Images.Media#query).
Schreibe einen Kommentar