参照(テーマ)の場合、プログラムでカラー値を取得します


115

このことを考慮:

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>

したがって、テーマの色テーマによって参照されます。プログラムでtheme_color(参照)を取得するにはどうすればよいですか?通常は使用しますgetResources().getColor()が、参照されているため、この場合は使用しません。

回答:


253

これは仕事をするはずです:

TypedValue typedValue = new TypedValue();
Theme theme = context.getTheme();
theme.resolveAttribute(R.attr.theme_color, typedValue, true);
@ColorInt int color = typedValue.data;

また、このコードを呼び出す前に、必ずテーマをアクティビティに適用してください。どちらかを使用:

android:theme="@style/Theme.BlueTheme"

マニフェストまたは呼び出しで(呼び出す前にsetContentView(int)):

setTheme(R.style.Theme_BlueTheme)

の中でonCreate()

私はあなたの値でそれをテストしました、そしてそれは完全に働きました。


おかげで私はまだあなたの解決策を試すことができませんが、エラーが発生します:stackoverflow.com/questions/17278244/…多分これで経験があるかもしれません...
セラフィムの

5
とにかく、あなたの解決策で私は0値の色(TypedValue {t = 0x0 / d = 0x0})を取得します...私はdeclare-styleableを使用せず、色への参照のみを使用します
Seraphimの

あなたの活動にテーマを適用していますか?
Emanuel Moecklin 2013年

5
テーマをアクティビティに適用したくない場合はContextThemeWrapper、テーマIDを使用してを作成し、そこからテーマを取得できます。
テッド・ホップ

1
この方法はandroid X(マテリアルデザイン)で機能します
BlackBlind

43

kotlinを使用している場合、受け入れられた回答に追加します。

@ColorInt
fun Context.getColorFromAttr(
    @AttrRes attrColor: Int,
    typedValue: TypedValue = TypedValue(),
    resolveRefs: Boolean = true
): Int {
    theme.resolveAttribute(attrColor, typedValue, resolveRefs)
    return typedValue.data
}

そしてあなたの活動ではあなたがすることができます

textView.setTextColor(getColorFromAttr(R.attr.color))


2
「統合」をありがとう。コトリンは使っていませんが、面白いです。
セラフィムの

5
TypedValueを外の世界から見えるようにします。そして、色については常に参照宣言を解決したいので、私はこれを持っています:(@ColorInt fun Context.getThemeColor(@AttrRes attribute: Int) = TypedValue().let { theme.resolveAttribute(attribute, it, true); it.data }ここではフォーマットが不適切ですが、問題ありません)
milosmns

1
使用法は次のようになりますval errorColor = context.getThemeColor(R.attr.colorError)
。– milosmns

aのデフォルト値も取得する、より一般的な方法ColorStateList@ColorInt fun Context.getThemeColor(@AttrRes attribute: Int) = obtainStyledAttributes(intArrayOf(attribute)).use { it.getColor(0, Color.MAGENTA) }Nick Butcherから)
gmk57

ColorStateList別のテーマ属性を参照している場合でも、全体を取得する究極の方法:(fun Context.getThemeColor(@AttrRes attribute: Int): ColorStateList = TypedValue().let { theme.resolveAttribute(attribute, it, true); AppCompatResources.getColorStateList(this, it.resourceId) }単色もラップされColorStateListます)。
gmk57

24

これは私のために働きました:

int[] attrs = {R.attr.my_attribute};
TypedArray ta = context.obtainStyledAttributes(attrs);
int color = ta.getResourceId(0, android.R.color.black);
ta.recycle();

あなたはそれから16進文字列を取得したい場合:

Integer.toHexString(color)

これは、ColorIntではなくColorResを返す必要があります。
Miha_x64

私はこれをgetColorResource(color)で使用し、リサイクルを呼び出さなかった。
Zeek Aran、

2

複数の色を取得したい場合は、以下を使用できます。

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

2

これをbuild.gradle(アプリ)に追加します。

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

そして、この拡張関数をコードのどこかに追加します。

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

0

複数の属性を取り、色整数の配列を返す簡潔なJavaユーティリティメソッドを次に示します。:)

/**
 * @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;
}

この点で、JavaはKotlinより優れていますか?
IgorGanapolsky

@IgorGanapolskyああ、正直わからない。私は自分のコードを他の誰かに役立つことを知っていたので共有しました!私はKotlinを知りませんが、Kotlinを使用してもコードの行数が少なくなるため、パフォーマンスは向上しないと思います。:P
varun

-1

描画可能への参照を探している人のために、あなたは使うべきfalseresolveRefs

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


変数typedValueを参照して何ですか?
BENN1TH

変数theme。*を参照していただきました。
BENN1TH
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.