web-dev-qa-db-de.com

Wie man Stilattribute programmgesteuert aus styles.xml abruft

Derzeit verwende ich entweder ein WebView oder ein TextView, um einige dynamische Daten eines Webservice in einer meiner Apps anzuzeigen. Wenn die Daten reinen Text enthalten, wird die Textansicht verwendet und ein Stil aus styles.xml angewendet. Wenn die Daten HTML (hauptsächlich Text und Bilder) enthalten, wird die Webansicht verwendet.

Diese WebView ist jedoch nicht gestylt. Daher sieht es ganz anders aus, als sonst bei TextView .. Ich habe gelesen, dass es möglich ist, den Text in einem WebView zu formatieren, indem einfach etwas HTML direkt in die Daten eingefügt wird. Das hört sich einfach an, aber ich möchte die Daten aus meiner Styles.xml als Werte verwenden, die in diesem HTML-Code erforderlich sind. Ich muss also nicht an zwei Speicherorten die Farben usw. ändern, wenn ich meine Stile ändere.

Wie könnte ich das tun? Ich habe einige umfangreiche Suchen durchgeführt, aber ich habe keine Möglichkeit gefunden, die verschiedenen Stilattribute aus Ihrer styles.xml abzurufen. Fehlt mir hier etwas oder ist es wirklich nicht möglich, diese Werte abzurufen?

Der Stil, den ich versuche, die Daten abzurufen, ist folgender:

<style name="font4">
    <item name="Android:layout_width">fill_parent</item>
    <item name="Android:layout_height">wrap_content</item>
    <item name="Android:textSize">14sp</item>
    <item name="Android:textColor">#E3691B</item>
    <item name="Android:paddingLeft">5dp</item>
    <item name="Android:paddingRight">10dp</item>
    <item name="Android:layout_marginTop">10dp</item>
    <item name="Android:textStyle">bold</item>
</style>

Ich interessiere mich hauptsächlich für die textSize und textColor.

66

Es ist möglich, benutzerdefinierte Stile programmgesteuert von styles.xml abzurufen. 

Definieren Sie einen beliebigen Stil in styles.xml:

<style name="MyCustomStyle">
    <item name="Android:textColor">#efefef</item>
    <item name="Android:background">#ffffff</item>
    <item name="Android:text">This is my text</item>
</style>

Rufen Sie nun die Stile so ab

// The attributes you want retrieved
int[] attrs = {Android.R.attr.textColor, Android.R.attr.background, Android.R.attr.text};

// Parse MyCustomStyle, using Context.obtainStyledAttributes()
TypedArray ta = obtainStyledAttributes(R.style.MyCustomStyle, attrs);

// Fetch the text from your style like this.     
String text = ta.getString(2);

// Fetching the colors defined in your style
int textColor = ta.getColor(0, Color.BLACK);
int backgroundColor = ta.getColor(1, Color.BLACK);

// Do some logging to see if we have retrieved correct values
Log.i("Retrieved text:", text);
Log.i("Retrieved textColor as hex:", Integer.toHexString(textColor));
Log.i("Retrieved background as hex:", Integer.toHexString(backgroundColor));

// OH, and don't forget to recycle the TypedArray
ta.recycle()
148
Ole

Die Antwort, die @Ole gegeben hat, scheint zu brechen, wenn bestimmte Attribute verwendet werden, z. B. shadowColor, shadowDx, shadowDy, shadowRadius (dies sind nur einige, die ich gefunden habe, es könnten noch mehr sein).

Ich habe keine Ahnung von warum dieses Problem auftritt, was ich nach hier frage, aber @AntoineMarques Codierungsstil scheint das Problem zu lösen.

Damit dies mit einem beliebigen Attribut funktioniert, würde es ungefähr so ​​aussehen


Definieren Sie zunächst ein Stylable, das die Ressourcen-IDs enthält

attrs.xml

<resources>     
    <declare-styleable name="MyStyle" >
        <attr name="Android:textColor" />
        <attr name="Android:background" />
        <attr name="Android:text" />
    </declare-styleable>
</resources>

Dann würden Sie im Code das tun, um den Text zu erhalten.

TypedArray ta = obtainStyledAttributes(R.style.MyCustomStyle, R.styleable.MyStyle);  
String text = ta.getString(R.styleable.MyStyle_Android_text);

Der Vorteil dieser Methode besteht darin, dass Sie den Wert über den Namen und nicht über einen Index abrufen.

40
PrivatMamtora

Die Antworten von Ole und PrivatMamtora funktionierten nicht gut für mich, aber das tat es.

Angenommen, ich wollte diesen Stil programmgesteuert lesen: 

<style name="Footnote">
    <item name="Android:fontFamily">@font/some_font</item>
    <item name="Android:textSize">14sp</item>
    <item name="Android:textColor">@color/black</item>
</style>

Ich könnte es so machen:

fun getTextColorSizeAndFontFromStyle(
    context: Context, 
    textAppearanceResource: Int // Can be any style in styles.xml like R.style.Footnote
) {
    val typedArray = context.obtainStyledAttributes(
        textAppearanceResource,
        R.styleable.TextAppearance // These are added to your project automatically.
    )
    val textColor = typedArray.getColorStateList(
        R.styleable.TextAppearance_Android_textColor
    )
    val textSize = typedArray.getDimensionPixelSize(
        R.styleable.TextAppearance_Android_textSize
    )

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val typeface = typedArray.getFont(R.styleable.TextAppearance_Android_fontFamily)

        // Do something with the typeface...

    } else {
        val fontFamily = typedArray.getString(R.styleable.TextAppearance_fontFamily)
            ?: when (typedArray.getInt(R.styleable.TextAppearance_Android_typeface, 0)) {
                1 -> "sans"
                2 -> "serif"
                3 -> "monospace"
                else -> null
            }

        // Do something with the fontFamily...
    }
    typedArray.recycle()
}

Ich habe mich von der Android TextAppearanceSpan-Klasse inspirieren lassen. Sie finden sie hier: https://Android.googlesource.com/platform/frameworks/base/+/master/core/Java/Android/text/style/TextAppearanceSpan.Java

0
Janosch Pelzer