===== Einfache Liste =====
Eine Liste anzuzeigen macht immer dann Sinn, wenn diese mehr oder weniger dynamisch generiert werden kann. Liegen die Daten also in einem ''array''- oder ''Listen''-Objekt vor kann dieses einfach an einen Adapter übergeben werden, welcher dann, je nach Typ mehr oder weniger vollautomatisch, die Listenanzeige erstellt.
Es wird davon ausgegangen dass ein Projekt ''SimpleList'' mit den Standardnamen [[android:preparationes_geht_los|erstellt]] wurde.
Grundsätzlich ist zu erwähnen dass diverse Möglichkeiten existieren eine Liste zu erstellen, hier werden die einfachsten Varianten gezeigt.
==== Android Standardansicht ====
Für das Layout wird ein ListView-Element verwendet. Dieses kann als einziges Element (statts des Layouts) oder als Kindelement eines Layouts bestehen. Wichtig ist nur die ID für den späteren Zugriff.
** activty_main.xml: **
Die Liste soll mit Daten gefüllt werden, welche hier der Einfachheit halber als vordefiniertes Array zur Verfügung stehen. Dies kann durchaus Sinn machen, meistens werden die Daten aber wohl während des Ablaufs generiert. Das ListView-Element muss wieder definiert werden. Diesem wird dann ein Adapter zugeweisen welcher zuvor "erstellt" wird. Dem Adapter werden hier Android-Standardansichten für die Liste und die Daten übergeben. Ein Adapter wird, vereinfacht ausgedrückt, immer iterrierend pro Datensatz aufgerufen um entsprechend ein Listenelement zu erzeugen.
Zu guter letzt wird hier ein ''OnItemClickListener'' verwendet, welcher in der MainActivity implementiert wird. So kann dann in der Methode ''onItemClick'' auf das Klick-Event eines Listeneintrages reagiert werden.
** MainActivity.java: **
public class MainActivity extends Activity implements OnItemClickListener {
private final static String TAG = MainActivity.class.getSimpleName();
// Daten für die Liste bereit stellen
private String[] aData = new String[] {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6" };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Listview initialisieren
ListView lvSimpleList = (ListView) findViewById(R.id.lvsimpleList);
// Adapter mit Android eigenen Views erstellen und setzen
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, android.R.id.text1, aData);
lvSimpleList.setAdapter(adapter);
// onItemClicklistener setzen
lvSimpleList.setOnItemClickListener(this);
}
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
Log.d(TAG, "onItemClick: Position = " + position);
}
}
{{:android:simplelist1.png?nolink&400|Einfache Standardliste}}
==== Eigenen Stil nutzen ====
Die oben beschriebene Variante reicht in den seltensten Fällen aus. Spätestens wenn ein Listeneintrag nicht nur ein Element enthält, unterschiedliche Listenelemente verwendet werden sollen oder einfach nur die Farbe verändert werden soll, wird es notwendig einen "eigenen" Adapter zu verwenden. Ein eigener Adapter macht es also möglich die Liste zu individualisieren.
Mit ''File => New => Class'' eine neue Klasse mit dem Namen ''ListViewAdapter'' erstellen. Diese neue Klasse erweitert nun den ''ArrayAdapter'' welcher im oberen Beispiel benutzt wurde. Hier muss noch der Datentyp der einzutragenden Daten angegeben werden.
Im Adapter werden 3 Felder für den ''Context'', die ''Layout-Id'' und die ''Daten'' benötigt, welche im ''Konstruktor'' initialisiert werden. In der zu überschreibenden Methode ''getView()'' findet alles wichtige statt.
Hier wird dem View-Element des Adapters zuerst die ID des Listenelementes mit hilfe eines ''LayoutInflaters'' übergeben. Dann muss das TextView-Element "geholt" werden um die Daten einzutragen. Im hier angegebenen Beispiel wird dann noch die Farbe abwechselnd geändert, ausserdem werden die Standardansichten verwendet. Es ist hier natürlich auch möglich eigene Elemente mit mehreren Einträgen zu nutzen.
** ListViewAdapter: **
// Klasse erweitert ArrayAdapter, Datentyp "String"
public class ListViewAdapter extends ArrayAdapter {
// deklaration der benötigten Felder
private Context context;
private int layoutId;
private String[] items;
public ListViewAdapter(Context context, int layoutId, String[] items) {
super(context, layoutId, items);
// initialisierung der Felder
this.context = context;
this.layoutId = layoutId;
this.items = items;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
// Layout zuweisen
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
view = inflater.inflate(layoutId, null);
// Daten in TextView-Element eintragen
TextView tvItem = (TextView) view.findViewById(android.R.id.text1);
tvItem.setText(items[position]);
// Farbwechsel
if (position % 2 == 0)
view.setBackgroundColor(Color.WHITE);
else
view.setBackgroundColor(Color.LTGRAY);
// angepasstes View-Element als Rückgabe
return view;
}
}
In der Klasse ''MainActivity'' ändert sich nur die Deklaration/Definition des Adapters von zuvor ''ArrayAdapter'' auf den soeben erstellten ''ListViewAdapter'', welcher ja eine Erweiterung dessen ist.
ListViewAdapter adapter = new ListViewAdapter(this, android.R.layout.simple_list_item_1, aData);
{{:android:simplelist2.png?nolink&400|Erweiterte Standardliste}}
==== Performance ====
Bei langen Listen ist es angeraten die View-Elemente im Adapter nur dann neu zu erzeugen wenn sie noch nicht existieren. Dies wird über eine Datenhalter-Klasse bewerkstelligt. Diese innere Klasse enthält alle schon erzeugten Listeneinträge.
** ListViewAdapter: **
// Klasse erweitert ArrayAdapter, Datentyp "String"
public class ListViewAdapter extends ArrayAdapter {
// deklaration der benötigten Felder
private Context context;
private int layoutId;
private String[] items;
public ListViewAdapter(Context context, int layoutId, String[] items) {
super(context, layoutId, items);
// initialisierung der Felder
this.context = context;
this.layoutId = layoutId;
this.items = items;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
// Datenhalter erzeugen
ViewHolder holder = null;
if (view == null) {
// Datenhalter initialisieren
holder = new ViewHolder();
// Layout zuweisen
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
view = inflater.inflate(layoutId, null);
// View-Element an Datenhalter übergeben
holder.listItem = (TextView) view.findViewById(android.R.id.text1);
// angepasstes View-Element an Datenhalter übergeben
view.setTag(holder);
}
else
holder = (ViewHolder) view.getTag();
// Daten in TextView-Element eintragen
holder.listItem.setText(items[position]);
// Farbwechsel
if (position % 2 == 0)
view.setBackgroundColor(Color.WHITE);
else
view.setBackgroundColor(Color.LTGRAY);
// angepasstes View-Element als Rückgabe
return view;
}
// innere Datenhalter-Klasse
static class ViewHolder {
TextView listItem;
}
}