Switch in Layout reagiert per onClick nicht auf schieben des Buttons.

  • Antworten:6
  • OffenNicht stickyNicht beantwortet
  • Forum-Beiträge: 22

07.08.2015, 13:29:40 via Website

Hallo,

ich habe in den Settings meiner App sehr viele Switches, um nicht 50 Listener in den Code zu packen, habe ich einfach den switches eine onClick Methode in der XML Datei hinzugefügt (allen die gleiche) . Die Methode prüft dann mithilfe von switch/case welcher Switch betätigt wurde. Jetzt ist das Problem, das man Switches ja auch "schieben" kann. Diese Aktion wird nicht als onClick registriert. Eine onChange gibt es ja anscheinend für die Layout File nicht.

Muss ich jetzt doch einen Listener für jeden Switch setzen? Oder gibt ggf. noch eine andere Möglichkeit?

Gruß
Markus

Antworten
Gelöschter Account
  • Forum-Beiträge: 438

07.08.2015, 13:52:12 via Website

Abgesehen davon, dass ich ein solches switch/case persönlich nicht besonders elegant finde und ohne einen Switch je benutzt zu haben: Ggf. kannst Du Switch ableiten und den CompoundButton.OnCheckedChangeListener(von dem ich mal ausgehe, dass er dann getriggert wird, wenn der Switch geschoben wird) so implementieren, dass er ein onClick auslöst, also so in etwa im Konstruktor:

this.setOnCheckedChangeListener (new CompoundButton.OnCheckedChangeListener() {
                                     void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                                         performClick();
                                     }
                                 } );

Im XML müsstest Du dann Switch durch Deine voll qualifizierte Subklasse ersetzen.

Alternativ könntest Du - falls du die Switches irgendwo gebündelt im Zugriff hast - einen solchen Listener auch jeweils zum Konstruktionszeitpunkt setzen.

HTH

Aktuelles Entwicklungsprojekt: (thinking) Sudoku Dojo Free (lightbulb)
Ich freue mich über Tester/innen.

Antworten
  • Forum-Beiträge: 22

07.08.2015, 14:21:46 via Website

Werde es jetzt so lösen:

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    CompoundButton.OnCheckedChangeListener multiListener = new CompoundButton.OnCheckedChangeListener() {

        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            switch (v.getId()){
                case R.id.switchVibra:
                    // Do something
                    break;
            }
       }
    });

    //on each switch
    ((Switch) findViewById(R.id.switchVibra)).setOnCheckedChangeListener(multiListener);
}

So kann ich wenigstens etwas die Switches zusammenfassen.

Antworten
Gelöschter Account
  • Forum-Beiträge: 438

07.08.2015, 14:33:25 via Website

Nur ein paar kleine Anmerkungen:

  • Wozu soll das switchim Listener gut sein? Du steckst diesen Listener doch immer nur in die Switches, die dieses Verhalten benötigen.
  • "Do something" ist mE in Deinem Szenario tatsächlich immer performClick().

P.S. Wenn's geholfen hat, wäre ein Klick auf den kleinen Daumen hoch Button sehr nett :D

P.P.S. Schonmal von Butterknife gehört? Das macht die ganzen cast/findViewByIdOrgien erheblich leichter lesbar.

Aktuelles Entwicklungsprojekt: (thinking) Sudoku Dojo Free (lightbulb)
Ich freue mich über Tester/innen.

Antworten
  • Forum-Beiträge: 1.904

07.08.2015, 15:39:18 via Website

Bei 50 Switches in den Einstellungen ist doch irgendwas komisch... Das scheint nicht sehr komfortabel zu sein. Aber sonst würde ich durch alle Childs iterieren und wenn das ein Switch ist, dann, wie du jetzt hast, einem Listener zuweisen. Im Listener anhand der Id entschieden, was für Aktionen ausgeführt werden. Wenn diese Aktionen nur Eintragungen in die SharedPreferences sind, dann solltest du mal einen Blick auf http://developer.android.com/guide/topics/ui/settings.html werfen.

— geändert am 07.08.2015, 15:39:45

Wenn dir mein Beitrag gefällt, kannst dich einfach mit dem 👍 "Danke"-Button auf der Website dieses Forums bedanken. 😀

Why Java? - Because I can't C#

Antworten
  • Forum-Beiträge: 22

07.08.2015, 16:03:25 via Website

Also kurz zum Hintergrund :

Die App steuert die Einstellungen eines externen GPS Empfängers mit einem Haufen Einstellungsmöglichkeiten. Da über die App mehrere dieser Empfänger verwaltet werden können, sind diese als Datensätze in einer SQLITE Datenbank hinterlegt.

Der Vertreiber des Empfängers wünscht sich hinter den Optionen einen solchen Switch zum an und ausschalten.

Nach Betätigung des Schalters sendet die App einen Befehl an GPS Empfänger.

Da der Weg des Befehls immer gleich ist und sich nur der Befehl ändert wird beim switch / case nur der Befehlstext geändert. Und danach der Befehl angesetzt und die neue Einstellung in der Datenbank gespeichert.

Antworten
Gelöschter Account
  • Forum-Beiträge: 438

07.08.2015, 16:58:11 via Website

Spricht in meinen Augen für folgende Lösung:

  • Eine eigene Klasse programmieren, die sowohl das OnClick-Listener-Interface, wie auch das OnCheckedChangeListener Interface implementieren und beide eine Methode (z.B. executeCommandForSwitch(final int viewId)) rufen - jeweils mit Übergabe der view-Id.
  • Die Methode (wo auch immer die dann angesiedelt ist - vermutlich in der Control-Schicht) trägt dann als statische Konfigurationsinformation noch eine Map in der die Zuordnung von View-Id zu Befehlszeichenkette enthalten ist.

Also in etwa so:

private static final Map<Integer, String> CONFIG = createConfig();

private static final Map<Integer, String> createConfig() {
    final Map<Integer, String> config = new HashMap<>();
    config.put(R.id.switchVibra, "TOGGLE VIBRATION");
    config.put(R.id.switchNightMode, "DISPLAY TOGGLE NIGHTMODE");
    [.... weitere 50 Konfigeinträge ....]
    return Collections.unmodifiableMap(config);
}

... irgendwo anders ....

public boolean executeCommandForSwitch(final int viewId) {
    final String gpsCommand = CONFIG.get(viewId);
    boolean commandExecutedSuccessfully = false;
    if (gpsCommand != null) {
        commandExecutedSuccessfully = mGpsReceiver.execute(gpsCommand);
    }
    return commandExecutedSuccessfully;
}

Das spart jeglichen switch und ist leicht erweiterbar.
Falls der Schalterzustand on/off zu anderen Befehlsketten führt, kann der Schlüsse der Map auch durch eine Tupel viewId + Zustand gebildet werden, das Muster bleibt das Gleiche.

— geändert am 07.08.2015, 16:58:51

Aktuelles Entwicklungsprojekt: (thinking) Sudoku Dojo Free (lightbulb)
Ich freue mich über Tester/innen.

[res][per]

Antworten