179 votes

Obtenir la valeur d'une couleur par programme lorsqu'il s'agit d'une référence (thème)

Considérez ceci :

styles.xml

<style name="BlueTheme" parent="@android:style/Theme.Black.NoTitleBar">
    <item name="theme_color">@color/theme_color_blue</item>
</style>

attrs.xml

<attr name="theme_color" format="reference" />

color.xml

<color name="theme_color_blue">#ff0071d3</color>

Ainsi, le couleur du thème est référencé par le thème. Comment puis-je obtenir la référence theme_color de manière programmatique ? Normalement, je devrais utiliser getResources().getColor() mais pas dans ce cas car il est référencé !

13voto

André Ramon Points 834

Ajoutez ceci à votre build.gradle (app) :

implementation 'androidx.core:core-ktx:1.1.0'

Et ajoutez cette fonction d'extension quelque part dans votre code :

@ColorInt
@SuppressLint("Recycle")
fun Context.themeColor(
    @AttrRes themeAttrId: Int
): Int {
    return obtainStyledAttributes(
        intArrayOf(themeAttrId)
    ).use {
        it.getColor(0, Color.MAGENTA)
    }
}

3voto

Webserveis Points 1102

J'utilise cette extension kotlin

@ColorInt
fun Context.getColorFromAttr( @AttrRes attrColor: Int
): Int {
    val typedArray = theme.obtainStyledAttributes(intArrayOf(attrColor))
    val textColor = typedArray.getColor(0, 0)
    typedArray.recycle()
    return textColor
}

échantillon

getColorFromAttr(android.R.attr.textColorSecondary)

2voto

Nicolas Points 1587

Si vous voulez obtenir plusieurs couleurs, vous pouvez utiliser :

int[] attrs = {R.attr.customAttr, android.R.attr.textColorSecondary, 
        android.R.attr.textColorPrimaryInverse};
Resources.Theme theme = context.getTheme();
TypedArray ta = theme.obtainStyledAttributes(attrs);

int[] colors = new int[attrs.length];
for (int i = 0; i < attrs.length; i++) {
    colors[i] = ta.getColor(i, 0);
}

ta.recycle();

0voto

varun Points 421

Voici une méthode utilitaire Java concise qui prend plusieurs attributs et renvoie un tableau d'entiers de couleur :)

/**
 * @param context    Pass the activity context, not the application context
 * @param attrFields The attribute references to be resolved
 * @return int array of color values
 */
@ColorInt
static int[] getColorsFromAttrs(Context context, @AttrRes int... attrFields) {
    int length = attrFields.length;
    Resources.Theme theme = context.getTheme();
    TypedValue typedValue = new TypedValue();

    @ColorInt int[] colorValues = new int[length];

    for (int i = 0; i < length; ++i) {
        @AttrRes int attr = attrFields[i];
        theme.resolveAttribute(attr, typedValue, true);
        colorValues[i] = typedValue.data;
    }

    return colorValues;
}

0voto

lightning mcqueen Points 133

Pour ceux qui cherchent une référence à une table de dessin, vous devriez utiliser false sur resolveRefs

theme.resolveAttribute(R.attr.some_drawable, typedValue, **false**);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X