web-dev-qa-db-fra.com

Comment récupérer des attributs de style par programmation à partir de styles.xml

J'utilise actuellement une vue Web ou une vue TextView pour afficher des données dynamiques provenant d'un service Web dans l'une de mes applications. Si les données contiennent du texte pur, il utilise TextView et applique un style de styles.xml . Si les données contiennent du HTML (principalement du texte et des images), il utilise WebView.

Cependant, cette WebView n'est pas stylée. Cela ressemble donc beaucoup à l'habituel TextView . J'ai lu qu'il était possible de styliser le texte d'une vue Web en insérant simplement du code HTML directement dans les données. Cela semble assez facile, mais j'aimerais utiliser les données de mon fichier Styles.xml comme valeurs requises dans ce code HTML afin de ne pas avoir à changer les couleurs, etc., à deux endroits si je change de style.

Alors, comment pourrais-je faire cela? J'ai effectué des recherches approfondies mais je n'ai trouvé aucun moyen de récupérer les différents attributs de style dans votre fichier styles.xml. Est-ce que je manque quelque chose ici ou est-il vraiment impossible de récupérer ces valeurs?

Le style que j'essaie d'obtenir des données est le suivant:

<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>

Je suis principalement intéressé par textSize et textColor.

66
Sander van't Veer

Il est possible de récupérer des styles personnalisés à partir de styles.xml par programmation. 

Définissez un style arbitraire dans 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>

Maintenant, récupérez les styles comme celui-ci

// 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

La réponse donnée par @Ole semble rompre avec certains attributs, tels que shadowColor, shadowDx, shadowDy, shadowRadius (ceux-ci ne sont que quelques-uns que j'ai trouvés, il pourrait y en avoir d'autres)

Je n'ai aucune idée quant à pourquoi ce problème se produit, ce que je demande à propos de ici , mais @AntoineMarques le style de codage semble le résoudre.

Pour que cela fonctionne avec n’importe quel attribut, ce serait quelque chose comme ceci


Tout d’abord, définissez un stylable pour contenir les identifiants de ressources comme suit

attrs.xml

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

Ensuite, dans le code, vous feriez ceci pour obtenir le texte.

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

L'avantage d'utiliser cette méthode est que vous récupérez la valeur par nom et non par index.

40
PrivatMamtora

Les réponses d'Ole et de PrivatMamtora n'ont pas bien fonctionné pour moi, mais cela a fonctionné.

Disons que je voulais lire ce style par programme: 

<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>

Je pourrais le faire comme ça:

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()
}

Je me suis inspiré de la classe TextAppearanceSpan d'Android. Vous pouvez le trouver ici: https://Android.googlesource.com/platform/frameworks/base/+/master/core/Java/Android/text/style/TextAppearanceSpan.Java

0
Janosch Pelzer