In Android gibt verschiedene Möglichkeiten auf Klicks zu reagieren.
Dabei hat jeder Ansatz seine eigenen Vor- und Nachteile – manchmal ist es aber auch nur der Geschmack, der darüber entscheidet, welche Variante man benutzt.
1. Das OnClick Attribut im XML-Tag
Besonders bei Buttons bietet es sich an, einfach das onClick-Attribut zu setzen. Dabei muss man beachten, dass man auch zusätzlich eine OnClick-Funktion, die den gleichen Namen wie der Attributwert trägt, in die zu dem Layout gehörige Java-Datei schreibt. Diese Funktion bekommt:
- als Rückgabewert: void
- als Parameter: View
Die Funktion wird nun immer aufgerufen, wenn der Button gedrückt wird.
Da der Funktionsname nun aber bei mehreren Views (z.B. Buttons) im Layout eingetragen werden kann, wird die View vom System mitgeliefert, die geklickt wurde.
Um nun in der onClick-Funktion zu unterscheiden, von welcher View die Funktion aufgerufen wurde, benutzt man die ID, die ein Element einmalig trägt.
Diese ID (als String) bekommt man durch View.getId();
Beispiel:
<Button
android:id="+id/myButton"
android:height="wrap_content"
android:width="wrap_content"
android:onClick="myClickHandler" />
Der Code kommt in die XML-Layout Datei.
@Override
public void myClickHandler( View target ) {
switch( target.getId() ) {
case R.id.myButton :
// Do stuff
}
}
Zu bemerken ist hier, dass die Id in Android eine Ressource ist, die intern den Datentyp Zahl hat.
+ Vorteil:
- Vergleichsweise wenig Platzaufwand
– Nachteil:
- Die Funktion wird bei jedem Klick aufgerufen, das heißt: der OnClickListener kann weder entfernt noch während der Laufzeit hinzugefügt werden.
2. Der setOnClickListener
Bei dieser Variante wird in dem Layout per Java der Button mit der Id gefunden und ein Listener für jeden Klick hinzugefügt. Der Button braucht also nur zusätzlich eine Id zu tragen.
<Button
android:id="+id/myButton"
android:height="wrap_content"
android:width="wrap_content"/>
Der Code kommt in die XML-Layout Datei.
@Override
public void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
Button button = (Button) findViewById( R.id.myButton );
button.setOnClickListener( new View.OnClickListener () {
@Override
public void onClick( View v ) {
// Do Stuff
}
}
}
Und dieser in die zu dem Layout gehörige Java-Datei. Außerdem kann man den OnClickListener auch wieder entfernen, indem man button.setOnClickListener( null );
aufgeruft.
+ Vorteil:
- dynamisches hinzufügen von Listenern möglich
– Nachteil:
- Aufblähen der onCreate Funktion, wenn man bei vielen Buttons einen Listener braucht
- Viel Code doppelt sich bei öfteren hinzufügen von den OnClickListenern
3. Das View.OnClickListener Interface
Man kann auch das View.OnClickListener Interface in die Activity implementieren. Dafür muss man dann die onClick Funktion in der Activity überschreiben.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
public void onClick( View v ) {
// Do Stuff
- for example switch( v.getId() )
}
}
Von einer beliebiegen anderen Funktion kann man dann button.setOnClickListener( this );
aufrufen um den OnClickListener hinzuzufügen.
+ Vorteil:
- dynamisches hinzufügen von Listenern möglich
– Nachteil:
- meine präferierte Variante
4. Der OP-All-You-Can-Do View.OnTouchListener
Beim OnClickListener wird nur jener Klick erkannt, bei dem kein anderer Finger schon aufliegt. Möchte man nun aber selbst bestimmen, bei welchem genauen Ereignis eine Aktion ausgeführt werden soll, kann man den View.OnTouchListener benutzen. Hier werden die Fälle deutlich präziert:
Anzeige.setOnTouchListener( new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int finger = 0;
int p = event.getActionIndex();
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
finger += 1;
processMouseDown((int) event.getX(p), (int) event.getY(p), event.getPointerId(p));
break;
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_UP:
finger -= 1;
processMouseUp((int) event.getX(p), (int) event.getY(p), event.getPointerId(p));
break;
case MotionEvent.ACTION_MOVE:
final int historySize = event.getHistorySize();
final int pointerCount = event.getPointerCount();
for (int h = 0; h < historySize; h++) {
for (int p1 = 0; p1 < pointerCount; p1++) {
processMouseMove((int) event.getHistoricalX(p1, h), (int) event.getHistoricalY(p1, h), event.getPointerId(p1));
}
}
for (int p1 = 0; p1 < event.getPointerCount(); p1++) {
processMouseMove((int) event.getX(p1), (int) event.getY(p1), event.getPointerId(p1));
}
}
return true;
}
}
+ Vorteil:
- dynamisches hinzufügen von Listenern möglich
- sehr differenziertes reagieren auf die verschiedenen Ereignisse möglich
– Nachteil:
- ein Wenig mehr Code nötig um gleiches wie beim OnClickListener zu erreichen