Android Selector Drawable mit VectorDrawables srcCompat
Lesezeit: 8 Minuten
Ich habe ein Problem mit der neuen Abwärtskompatibilität mit VectorDrawables. In der Support Library 23.2 wurde ein neues Feature zur Abwärtskompatibilität mit Android VectorDrawables eingeführt.
Ich habe eine ImageView, der ein SelectorDrawable zugewiesen ist. Dieses Drawable enthält mehrere VectorDrawables, daher dachte ich, ich sollte app:srcCompat aus Kompatibilitätsgründen verwenden. Aber es funktioniert nicht auf meinem Galaxy S2 mit Android 4.1.2.
Bei der Verwendung dieses SelectorDrawable mit srcCompat erhalte ich diesen Fehler:
Caused by: android.content.res.Resources$NotFoundException: File res/drawable/ Caused by: android.content.res.Resources$NotFoundException: File res/drawable/ic_gps_fixed_24dp.xml from drawable resource ID #0x7f0201c1
at android.content.res.Resources.loadDrawable(Resources.java:1951)
at android.content.res.Resources.getDrawable(Resources.java:672)
at android.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:173)
at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:881).xml from drawable resource ID #0x7f0201c1
Die Verwendung von android:src ist noch schlimmer.
Wenn ich eines der Vektor-Drawables mit app:srcCompat verwende, funktioniert alles einwandfrei. Ich denke also, es ist ein Problem mit dem SelectorDrawable und der Kompatibilität.
Hat jemand das gleiche Problem gehabt und eine Lösung gefunden oder ist es derzeit nicht möglich, VectorDrawables in SelectorDrawables vor Android 5 zu verwenden?
Aber: “Die Verwendung von app:srcCompat und setImageResource() funktioniert weiterhin”, also sollte app:srcCompat in 23.3 noch funktionieren. oder nicht?
– marilion91
20. April 2016 um 11:11 Uhr
Ja, die Verwendung von app:srcCompat funktioniert immer noch, sodass Sie ein VectorDrawable auf eine ImageView setzen können. Das Laden der Drawables in eine xml-Zustandsliste funktioniert jedoch leider nicht mehr
– Jahnold
20. April 2016 um 11:25 Uhr
Marion91
Einige Dinge haben sich geändert, seit ich diese Frage gestellt habe, also werde ich sie selbst beantworten.
Sie müssen dies zu jeder Aktivität hinzufügen, bei der Sie VectorDrawables auf Geräten unter Android 5.0 (Codename Lollipop, API-Level 21) verwenden möchten:
Sie können also jetzt VectorDrawables in DrawableContainers verwenden, aber es kann immer noch einige Probleme verursachen, wie in den obigen Quellen erwähnt, also verwenden Sie es mit Vorsicht.
Ich habe diese Funktion in meiner App bisher nicht wieder aktiviert, aber ich werde mit meiner nächsten großen Version viele meiner Symbole auf VectorDrawables umstellen und dann tiefer in dieses Thema eintauchen.
“Sie müssen dies zu jeder Aktivität hinzufügen, bei der Sie VectorDrawables auf Geräten unter Android 5 verwenden möchten” stimmt nicht, wir brauchen das sogar für Android 15
– Stallanz
11. August 2016 um 15:09 Uhr
@stallianz Android 5 entspricht API-Level 21. Verwechseln Sie Release-Versionen nicht mit API-Versionen.
– F43nd1r
6. September 2016 um 12:55 Uhr
wo benutzt du AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); ?Ich habe es benutzt, aber ich erhalte jetzt den Fehler XmlPullParserException: Binary XML file line #4: invalid drawable tag vector
– Irgendwer irgendwo
5. Oktober 2017 um 14:15 Uhr
@ F43nd1r Nun, nennen Sie es zumindest Android 5.0. Android 5 ist mehrdeutig.
– hqzxzwb
25. November 2017 um 4:05 Uhr
Sergej Wassilenko
Wie @Jahnold im Kommentar zu der Frage erwähnte, wurde die Unterstützung für das Laden von Vector Drawable aus einer XML-Zustands-XML-Liste in 23.3 entfernt.
Ich habe jedoch mehrere Ansätze gefunden, die helfen können.
1. Verwendung von Tint
Der Ansatz ist geeignet, wenn sich die Drawables aus der ausgewählten Zustandsliste nur durch Farben unterscheiden.
Erstellen Sie zunächst nur einen Vektor, der mit Farbton und Weiß gezeichnet werden kann fillColor:
Der Ansatz eignet sich, wenn Sie für die Zustandsliste Vektorzeichen verwenden, die sich nicht nur durch eine Farbe, sondern auch durch eine Figur unterscheiden, sodass Sie mehrere verschiedene xml-Dateien erstellen müssen. Dann können Sie erstellen StateListDrawable programmgesteuert, wie in einer Antwort gezeigt.
Ich verbringe eine Stunde, um das zu finden button_tint.xml Datei sollte unter platziert werden /res/color Mappe. Also, vergiss es nicht.
– Nguyen Minh Binh
30. Juni 2016 um 4:07 Uhr
Wahrscheinlich sollten Sie den Farbton und den Farbtonmodus nicht im Drawable selbst definieren. Dies schränkt die Wiederverwendbarkeit der Drawables ein. Wenn der Designer beschließt, die Farbe zu ändern oder dasselbe Symbol in anderen Farben zu verwenden, müssen Sie das Drawable duplizieren, anstatt es nur mit einem Stil usw. zu tönen
– Christoph Perry
11. Juli 2016 um 19:06 Uhr
@Ghristopher Perry In diesem Fall können Sie den zweiten Ansatz verwenden.
– Sergej Wassilenko
12. Juli 2016 um 8:13 Uhr
Das funktioniert! Stellen Sie sicher, dass Sie android:tint und nicht app:tint verwenden.
– Eino Gourdin
21. Februar 2020 um 8:26 Uhr
Wolodymyr
Nach dem Anschauen Neuigkeiten in der Support-Bibliothek – Google I/O 2016 Mir ist eine nützliche Methode in der aufgefallen AppCompatResources Klasse. Das ist AppCompatResources#getColorStateList(Context context, int resId). Mit Hilfe dieser Methode habe ich einen Selektor mit Vektordrawables implementiert. Hier ist meine Farbauswahldatei icon_selector:
In der Anwendungsklasse hinzugefügt.
app build.gradle in defaultConfig
vectorDrawables.useSupportLibrary = true
Ich schlage diese Problemumgehung vor, um die Farbänderung basierend auf dem Status vorzunehmen: Legen Sie ein normales, weißes VectorDrawable fest und lassen Sie den Farbton den Farbwähler haben.
Dies wurde getestet, um sogar auf einem Emulator mit Android API 16 zu funktionieren, und es funktioniert natürlich auch, wenn Sie “vectorDrawables.useSupportLibrary = true” in Gradle festlegen.
Beispiel: Die erste Ansicht ist aktiviert und die zweite deaktiviert:
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
disabledSendMessageButton.isEnabled = false
}
}
Unterstützung für das Laden von Vektor-Drawables aus Ressourcen wurde in Version 23.3 entfernt – plus.google.com/+AndroidDevelopers/posts/iTDmFiGrVne
– Jahnold
20. April 2016 um 10:57 Uhr
Aber: “Die Verwendung von app:srcCompat und setImageResource() funktioniert weiterhin”, also sollte app:srcCompat in 23.3 noch funktionieren. oder nicht?
– marilion91
20. April 2016 um 11:11 Uhr
Ja, die Verwendung von app:srcCompat funktioniert immer noch, sodass Sie ein VectorDrawable auf eine ImageView setzen können. Das Laden der Drawables in eine xml-Zustandsliste funktioniert jedoch leider nicht mehr
– Jahnold
20. April 2016 um 11:25 Uhr