wake-up-neo.net

Wie referenzieren Sie Stilattribute aus einem Zeichenobjekt?

Ich möchte 2 auswählbare Themen für meine Bewerbung haben. Um dies zu tun, habe ich einige Attribute definiert:

 <attr format="color" name="item_background" />

Dann erstellte ich beide Themen wie folgt:

  <style name="ThemeA">
     <item name="item_background">#123456</item>
 </style>

 <style name="ThemeB">
     <item name="item_background">#ABCDEF</item>
 </style>

Diese Methode funktioniert hervorragend, so dass ich problemlos mehrere Designs erstellen und ändern kann. Das Problem ist, dass es scheint, dass es nur in Ansichten und nicht in Drawables verwendet werden kann.

Wenn Sie beispielsweise auf einen Wert aus einer Ansicht in einem Layout verweisen, wird Folgendes ausgeführt:

 <TextView Android:background="?item_background" />

Dasselbe in einem Drawable zu tun, bedeutet jedoch nicht:

 <shape Android:shape="rectangle">
     <solid Android:color="?item_background" />
 </shape>

Ich erhalte diesen Fehler beim Ausführen der Anwendung:

    Java.lang.UnsupportedOperationException: Can't convert to color: type=0x2

Wenn ich anstelle von ?item_background eine fest codierte Farbe verwende, funktioniert sie, aber ich kann meine Designs nicht verwenden. Ich habe auch ?attr:item_background ausprobiert, aber dasselbe passiert.

Wie kann ich das machen? Und warum funktioniert es in Ansichten, aber nicht in Drawables? Ich kann diese Einschränkung nirgendwo in der Dokumentation ... finden.

84
MM.

Nach meiner Erfahrung ist es nicht möglich, ein Attribut in einem XML-Zeichenelement zu referenzieren.
Um ein Thema zu erstellen, müssen Sie:

  • Erstellen Sie eine XML-Zeichnung pro Thema.
  • Fügen Sie die gewünschte Farbe direkt mit dem @color-Tag oder dem #RGB-Format ein.

Machen Sie ein Attribut für Ihre Zeichen in attrs.xml .

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <!-- Attributes must be lowercase as we want to use them for drawables -->
   <attr name="my_drawable" format="reference" />
</resources>

Fügen Sie Ihrem theme.xml Ihre Zeichnung hinzu.

<style name="MyTheme" parent="@Android:style/Theme.NoTitleBar">
   <item name="my_drawable">@drawable/my_drawable</item>
</style>

Verweisen Sie auf Ihr Zeichen in Ihrem Layout anhand Ihres Attributs.

<TextView Android:background="?my_drawable" />
147
L. G.

Beginnend mit Lollipop (API 21) wird diese Funktion unterstützt, siehe https://code.google.com/p/Android/issues/detail?id=26251 .

Wenn Sie jedoch Geräte ohne Lollipop anvisieren, verwenden Sie sie nicht, da dies zum Absturz führen würde. Verwenden Sie stattdessen die Problemumgehung in der akzeptierten Antwort.

15
marmor

Es ist zwar nicht möglich, Stilattribute aus Zeichenobjekten auf pre-Lollipop -Geräten zu referenzieren, es ist jedoch für Farbstatuslisten möglich. Sie können die Methode AppCompatResources.getColorStateList (Context context, int resId) } aus der Android Support Library verwenden. Der Nachteil ist, dass Sie diese Farbstatuslisten programmgesteuert festlegen müssen.

Hier ist ein sehr einfaches Beispiel.

color/my_color_state.xml

<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
  <item Android:state_checked="true" Android:color="?colorControlActivated" />
  <item Android:color="?colorControlNormal" />
</selector>

Ein Widget, das eine Farbstatusliste benötigt:

<RadioButton
  Android:id="@+id/radio_button"
  Android:text="My Radio" />

Und das Wichtigste:

ColorStateList csl = AppCompatResources.getColorStateList(context, R.color.my_color_state);    
RadioButton r = (RadioButton) findViewById(R.id.radio_button);
r.setTextColor(csl);

Nun, nicht der eleganteste oder kürzeste Weg, aber dies ist die Funktion der Android Support Library, damit ältere Versionen (Pre-Lollipop) von Android funktionieren.

Leider funktioniert die ähnliche Methode für Drawables nicht mit Stilattributen.

4
rubo

Wie @marmor mitteilte, wird dies jetzt von API 21 unterstützt. Für diejenigen, die ältere Versionen von Android unterstützen müssen, können Sie diese Funktion verwenden. Mit der v7-Unterstützungsbibliothek können Sie sie weiterhin in Apps mit minimalem SDK-Level bis hinunter zu 7 verwenden. 

Die AppCompatImageView in der v7 Android Support Library enthält eine fehlerfreie Implementierung dieser Funktion. Ersetzen Sie einfach Ihre Verwendungen von ImageView durch AppCompatImageView.

0
Benjamin