onClickListener auf Buttons die im Code erzeugt wurden setzen.

SchokoMuh

Mitglied
Erst mal ein ganz freundlich Hallo,

dann hoffe ich das ich meine Frage im richtigen Forum stelle.
Dann sollte ich vielleicht noch erwähnen das ich erst seit 3 Monaten durch Selbststudium mit Java und Android arbeite also bitte ich um ein bisschen nachsicht.

So nun mal zu meinem Problem.
ich habe mir ein Programm geschrieben mit dem ich aus einer CSV Datei daten auslese und die Überschriften dann in Buttens als Text zuweise.
Ich habe auch 2 feste Buttons die ich schon über den onClickListener (Activity als Listener) abfrage. Soweit so gut.
Meine frage nun ist wie kann ich einen onClickListener für die im Code erzeugten Buttons anlegen, ich gebe ihnen ja mit .setId eine int iD.

[CODE lang="java" highlight="43-55"]public class DataInputActivity extends AppCompatActivity implements View.OnClickListener {

private static final int requCode = 7;
private List csvReaded = new ArrayList();
private int iDZaehler =0;
private String[] spalten;
private int spaltenAnzahl = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_data_input);

Button bTSuchen = findViewById(R.id.bTSuchen);
Button bTHinzufuegen = findViewById(R.id.bTHinzufuegen);

bTSuchen.setOnClickListener(this);
bTHinzufuegen.setOnClickListener(this);
}
@Override
public void onClick(View v) {

switch (v.getId()){
case R.id.bTSuchen:
goToSuchen();
return;
case R.id.bTHinzufuegen:

return;
default:
return;
}
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.data_input_menu, menu);
return super.onCreateOptionsMenu(menu);

}

public Button erzeugeButton(String text, int id){
LinearLayout.LayoutParams lllp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,200);
lllp.setMargins(10,10,10,0);
Button button = new Button(getApplicationContext());
button.setLayoutParams(lllp);
button.setGravity(Gravity.CENTER);
button.setText(text);
button.setBackgroundColor(Color.GRAY);
button.setTextSize(TypedValue.COMPLEX_UNIT_SP,20);
button.setId(id);

return button;
}


public void erweitereLL(){
LinearLayout linearLayout = findViewById(R.id.dA_LLv);

for (int i = 0;i <= spalten.length-1;i++){
linearLayout.addView(erzeugeButton(spalten, i));
}


}[/CODE]

Währe echt super wenn mir jemand einen tip oder einen link zu einer Seite geben könnte die sich mit dem Thema beschäftigt.
 
Beste Antwort
K
Also was ich gezeigt habe, war erst einmal eine Methodenreferenz. Das ist kein Lambda Ausdruck. Aber wenn man sich irgendwas durchliest, dann wird das alles in einem Rutsch behandelt und sowohl ein Lambda Ausdruck als auch eine Methodenreferenz setzen ein sogenanntes Funktionales Interface voraus.

Einfach einmal als schneller Überblick:

Die Methode setOnClickListener erwartet einen Parameter vom Typ View.onClickListener.
View.OnClickListener ist ein Interface mit genau einer zu implementierenden Methode. (==> Funktionale Interfaces haben genau eine zu implementierende Methode!)

Das kann man auf mehrere Wege bekommen:
a) Eine Klasse implementiert das Interface. Das ist der Weg, den Du derzeit verwendet hast:
public class...

SchokoMuh

Mitglied
Also zum einen muss sich ein Spinner öffnen aus dem ich dann die Spalte einer Datenbank auswählen kann in welche dann die vorher schon ausgelesenen Daten schreibe und der Button sollte seine Farbe ändern. Das ist auch soweit kein Problem nur weiß ich nicht wie ich die Buttons für den onClickListener Initialisiere. Ich weiß ja jetzt noch nicht wie viele Buttons zur Laufzeit erstellt werden. Ich hab da sowas wie eine Schleife im Kopf aber leider überhaupt keine Idee wie ich das umsetzten muss.

Oder kann ich den onClickListener bei der Erstellung der Buttons gleich drauf setzen? Probier ich gleich mal.
 

SchokoMuh

Mitglied
Ich verstehe die Frage nicht ganz, das funktioniert genauso wie mit den "festen" Buttons. Was soll denn beim Click auf so einen Button passieren?
Also zum einen muss sich ein Spinner öffnen aus dem ich dann die Spalte einer Datenbank auswählen kann in welche dann die vorher schon ausgelesenen Daten schreibe und der Button sollte seine Farbe ändern. Das ist auch soweit kein Problem nur weiß ich nicht wie ich die Buttons für den onClickListener Initialisiere. Ich weiß ja jetzt noch nicht wie viele Buttons zur Laufzeit erstellt werden. Ich hab da sowas wie eine Schleife im Kopf aber leider überhaupt keine Idee wie ich das umsetzten muss.

Oder kann ich den onClickListener bei der Erstellung der Buttons gleich drauf setzen? Probier ich gleich mal.
 

SchokoMuh

Mitglied
Ist schon ab und zu lustig wie es läuft. Ich mach jetzt seit gestern an dem ding rum und komm auf keine Lösung und beim schreiben fällt es mir dann auf.
Update:
den onClicklistener zu setzten hab ich jetzt dann auch verstanden aber wie bring ich das mit der iD jetzt der Switch Case anweisung bei?
 
K

kneitzel

Gast
den onClicklistener zu setzten hab ich jetzt dann auch verstanden aber wie bring ich das mit der iD jetzt der Switch Case anweisung bei?
Wenn Du da Aktionen haben willst abhängig von der id, dann kann Du statt einer starren switch Anweisung z.B. eine Map nutzen.

Nur was baust Du da für eine Map? Du könntest Aufrufe speichern, also von der id verweist Du in der Map auf z.B. einen Consumer von der View des Click events.

Aber dann macht das natürlich keinen Sinn, denn statt einer gemeinsamem onClick Methode, die dann die jeweilige Unterroutine aufruft, könntest Du direkt die entsprechende Methode einbinden in dem Listener.

Du machst also kein .setOnClickListener(this); (Was ich so eh für schlecht halte) sondern Du gibst eine direkte Methodenreferenz:
.setOnClickListener(this::onClick); sollte deinen bisherigen Aufrufen das Gleiche machen.

Und wenn Du dann Methoden entsprechend dem, was sie machen, benennst, dann kannst da sauberen, lesbaren Code schreiben.
(Und natürlich verschwindet das implements View.OnClickListener bei der Klasse!)
 
K

kneitzel

Gast
Also was ich gezeigt habe, war erst einmal eine Methodenreferenz. Das ist kein Lambda Ausdruck. Aber wenn man sich irgendwas durchliest, dann wird das alles in einem Rutsch behandelt und sowohl ein Lambda Ausdruck als auch eine Methodenreferenz setzen ein sogenanntes Funktionales Interface voraus.

Einfach einmal als schneller Überblick:

Die Methode setOnClickListener erwartet einen Parameter vom Typ View.onClickListener.
View.OnClickListener ist ein Interface mit genau einer zu implementierenden Methode. (==> Funktionale Interfaces haben genau eine zu implementierende Methode!)

Das kann man auf mehrere Wege bekommen:
a) Eine Klasse implementiert das Interface. Das ist der Weg, den Du derzeit verwendet hast:
public class DataInputActivity extends AppCompatActivity implements View.OnClickListener {

Das ist prinzipiell ok, aber was mir etwas missfällt ist, dass dieses Interface ja kein Verhalten der Activity aufzeigt. Wenn es ein Interface LautGeben gäbe, dann könnte ein Hund das Interface implementieren. Denn der Hund hat ein Verhalten, bei dem er Laut gibt (er bellt). Das sehe ich hier nicht so wirklich.
Und zum anderen hast du eine Methode onClick in der Activity. Was macht onClick? Das sagt nichts aus. Eine Methode wäre gotoSearch -> was die macht, ist eher klar.

b) Anonyme Klasse:
Du kannst natürlich jederzeit eine anonyme Klasse erzeugen. Das wäre dann etwas wie (im Editor geschrieben - Tippfehler bitte verzeihen:
Java:
someButton.setOnClickListener(new View.ClickListener() {
    @Override
    public void onClick(View v) {
        // Whatever
    }
})
Viel Code und wieder ein onClick, das nicht sagt, WAS es macht sondern nur, WANN es ausgeführt wird.

Das waren die beiden "alten" Wege. Mit Java 8 ist dann ein Bereich dazu gekommen, der eine Art funktionale Programmierung mit einbringen sollte. Damit verbunden war, dass es Funktionale Interfaces gibt. Und das Interface hat nur eine Methode onClick, daher ist es funktional. Und damit gehen Lambda Ausdrücke und Methodenreferenzen:

c) Lambda Ausdruck
someButton.setOnClickListener(v -> doSomething(v));
Hier hast Du erst den Parameter (bei mehreren kommen die in Klammern, also z.B. "(a, b, c)"), dann den Pfeil ("->") und dann den Code, der den Parameter nutzen kann. Der Code kannauch ein ganzer Block mit { .. } sein, wobei das etwas ist, das als unschön angesehen wird, da schnell unleserlich. Lieber in eine Methode packen und dann die Methode aufrufen.

d) Methoden Referenz
someButton.setOnClickListener(this::doSomething);
Hier wird nur die Methode angegeben, die aufgerufen werden soll. In der aktuellen Instanz soll doSomething aufgerufen werden. Damit das funktionieren kann, muss doSomething natürlich von der Signatur her passen - Der Name darf natürlich unterschiedlich sein, aber die Parameter und Rückgabetyp müssen passen, damit das Interface erfüllt ist.

Das wäre auf die Schnelle und Kürze eine Übersicht zu dem Thema.
 
Beste Antwort
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Frage zu OnClickListener. Verständnisproblem Android & Cross-Platform Mobile Apps 5
W Wie kann man OnClicklistener und OnCheckedChangeListener zusammen ausführen Android & Cross-Platform Mobile Apps 18
MaxG. Android Absturz bei Aufruf von onClickListener() Android & Cross-Platform Mobile Apps 8
G OnCLICKListener - OnTOUCHListener Android & Cross-Platform Mobile Apps 2
D Android OnClickListener funktioniert auf LinearLayout nicht Android & Cross-Platform Mobile Apps 6
L Bitmap mit OnClickListener Android & Cross-Platform Mobile Apps 8
H Android TranslateAnimation und OnClickListener Android & Cross-Platform Mobile Apps 2
L Hintergrund eines Switch(Buttons) ändern Android & Cross-Platform Mobile Apps 3
D Android dynamische Buttons positionieren Android & Cross-Platform Mobile Apps 1
N Android Zwei Buttons gleichzeitig drücken Android & Cross-Platform Mobile Apps 9
H Buttons färben sich mit, beim Hintergrund ändern Android & Cross-Platform Mobile Apps 3
D Hilfe! es geht um Buttons und Sounds Android & Cross-Platform Mobile Apps 14
K Dynamische (Image)Buttons, Größe bestimmen Android & Cross-Platform Mobile Apps 4
V Buttons bei Klick hinzufügen Android & Cross-Platform Mobile Apps 2
V Buttons zur Actionbar hinzufügen Android & Cross-Platform Mobile Apps 4
L Android Bildschirm bleibt dunkel nach neustarten der App nach betätigen des Home-Buttons Android & Cross-Platform Mobile Apps 3
D Android Viele Buttons und ein Layout Android & Cross-Platform Mobile Apps 6
K Verständisfrage bzgl. Buttons und ihnen eine Funktion geben. Android & Cross-Platform Mobile Apps 3
P Buttons im + anordnen Android & Cross-Platform Mobile Apps 2
T Android AlertDialog; Buttons ändern Android & Cross-Platform Mobile Apps 4
H Buttons werden falsch angeordent Android & Cross-Platform Mobile Apps 2
F Buttons und awt? Android & Cross-Platform Mobile Apps 7
N "Schöne" Datatable in Android und setzen von Parametern von Textview im Code Android & Cross-Platform Mobile Apps 5
W Code läuft unter SDK 27 aber nicht SDK 30 Android & Cross-Platform Mobile Apps 17
M QR-Code auslesen mit Tabletkamera Android & Cross-Platform Mobile Apps 3
C Auf Play Store verlinken - Code in einer Extraklasse Android & Cross-Platform Mobile Apps 1
D HTML Code von Website abrufen Android & Cross-Platform Mobile Apps 26
K Android Code so OK? Android & Cross-Platform Mobile Apps 0
C Android Code in mehrere .java verteilen Android & Cross-Platform Mobile Apps 6
S Android Speichern von Informationen in Code oder extern Android & Cross-Platform Mobile Apps 0
M Code effizienter machen Android & Cross-Platform Mobile Apps 16
R Android YouTube Video per Code streamen Android & Cross-Platform Mobile Apps 5
P Brauche Hilfe bei Code Snippet Android & Cross-Platform Mobile Apps 10
L Android Android über Java Code connecten? Android & Cross-Platform Mobile Apps 2
A Android Android-Code.de - Das Android-Entwickler Forum Android & Cross-Platform Mobile Apps 3
R Android Ist das ein akzeptabler Code? Android & Cross-Platform Mobile Apps 7
H Mjpeg Code läuft unter Java jedoch nicht unter Android? Android & Cross-Platform Mobile Apps 11
J Android QR-Code Scanner mit OpenCV/JavaCV Android & Cross-Platform Mobile Apps 1
P J2ME Code-Beispiele Android & Cross-Platform Mobile Apps 2
2 Code ineffizient? Android & Cross-Platform Mobile Apps 6
H HELP! Code verbessern? Android & Cross-Platform Mobile Apps 3

Ähnliche Java Themen

Neue Themen


Oben