Beispielsweise weist die Standardschaltfläche die folgenden Abhängigkeiten zwischen ihren Status und Hintergrundbildern auf:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
<item android:state_window_focused="false" android:state_enabled="false"
android:drawable="@drawable/btn_default_normal_disable" />
<item android:state_pressed="true"
android:drawable="@drawable/btn_default_pressed" />
<item android:state_focused="true" android:state_enabled="true"
android:drawable="@drawable/btn_default_selected" />
<item android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
<item android:state_focused="true"
android:drawable="@drawable/btn_default_normal_disable_focused" />
<item
android:drawable="@drawable/btn_default_normal_disable" />
</selector>
Wie kann ich meinen eigenen benutzerdefinierten Status definieren (smth like android:state_custom
), um dann das visuelle Erscheinungsbild meiner Schaltfläche dynamisch zu ändern?
Antworten:
Die durch @ (Ted Hopp) angegebene Lösung funktioniert, muss jedoch etwas korrigiert werden: In der Auswahl benötigen die Elementzustände ein Präfix "app:", da der Inflater den Namespace sonst nicht richtig erkennt und stillschweigend fehlschlägt. Zumindest passiert mir das.
Gestatten Sie mir, hier die gesamte Lösung mit einigen weiteren Details zu melden:
Erstellen Sie zunächst die Datei "res / values / attrs.xml":
Definieren Sie dann Ihre benutzerdefinierte Klasse. Beispielsweise kann es sich um eine Klasse "FoodButton" handeln, die von der Klasse "Button" abgeleitet ist. Sie müssen einen Konstruktor implementieren. Implementieren Sie dieses, das vom Inflater verwendet zu werden scheint:
Über der abgeleiteten Klasse:
Auch Ihre Zustandsvariablen:
Und ein paar Setter:
Überschreiben Sie dann die Funktion "onCreateDrawableState":
Schließlich das heikelste Stück dieses Puzzles; Der Selektor, der die StateListDrawable definiert, die Sie als Hintergrund für Ihr Widget verwenden. Dies ist die Datei "res / drawable / food_button.xml":
Beachten Sie das Präfix "app:", während Sie bei Standard-Android-Status das Präfix "android:" verwendet hätten. Der XML-Namespace ist entscheidend für eine korrekte Interpretation durch den Inflater und hängt von der Art des Projekts ab, in dem Sie Attribute hinzufügen. Wenn es sich um eine Anwendung handelt, ersetzen Sie com.mydomain.mypackage durch den tatsächlichen Paketnamen Ihrer Anwendung (Anwendungsname ausgeschlossen). Wenn es sich um eine Bibliothek handelt, müssen Sie "http://schemas.android.com/apk/res-auto" verwenden (und Tools R17 oder höher verwenden). Andernfalls werden Laufzeitfehler angezeigt.
Ein paar Anmerkungen:
Es scheint, dass Sie die Funktion "refreshDrawableState" nicht aufrufen müssen, zumindest funktioniert die Lösung in meinem Fall so wie sie ist
Um Ihre benutzerdefinierte Klasse in einer Layout-XML-Datei verwenden zu können, müssen Sie den vollständig qualifizierten Namen angeben (z. B. com.mydomain.mypackage.FoodButton).
Sie können Standardzustände (z. B. Android: gedrückt, Android: aktiviert, Android: ausgewählt) mit benutzerdefinierten Zuständen verwechseln, um kompliziertere Zustandskombinationen darzustellen
quelle
refreshDrawableState
ist definitiv wichtig. Ich bin mir nicht ganz sicher, wann es wirklich gebraucht wird. In meinem Fall wurde es jedoch benötigt, um den Status programmgesteuert festzulegen. Ich denke, es wird möglicherweise automatisch von der View-Klasse im onTouchEvent aufgerufen. Ich füge es besser in die setSelected-Methode ein.boolean
? Oder arbeiten Selektoren nur mit Booleschen Werten?Dieser Thread zeigt, wie Sie Schaltflächen und dergleichen benutzerdefinierte Status hinzufügen. (Wenn Sie nicht können die neuen Google - Gruppen in Ihrem Browser sehen, gibt es eine Kopie des Themas hier .)
quelle
Bitte vergessen Sie nicht,
refreshDrawableState
innerhalb des UI-Threads aufzurufen :Ich habe viel Zeit gebraucht, um herauszufinden, warum mein Knopf seinen Zustand nicht ändert, obwohl alles richtig aussieht.
quelle