참조 (테마) 일 때 프로그래밍 방식으로 색상 값 가져 오기


116

이걸 고려하세요:

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()하지만이 경우에는 참조되기 때문에 사용 하지 않습니다!

답변:


254

이 작업을 수행해야합니다.

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/… 아마도이 경험이있을 수 있습니다 ...
Seraphim 's

5
어쨌든, 당신의 솔루션으로 나는 0 값 색상을 얻습니다 (TypedValue {t = 0x0 / d = 0x0}) ... 저는 declare-styleable을 사용하지 않고 색상에 대한 참조 만 사용합니다
Seraphim 's

활동에 테마를 적용합니까?
Emanuel Moecklin 2013 년

5
활동에 테마를 적용하지 않으려면 ContextThemeWrapper테마 ID를 사용하여을 생성 한 다음 그로부터 테마를 검색 할 수 있습니다 .
Ted Hopp

1
이 방법은 안드로이드 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
"통합"에 감사드립니다. kotlin을 사용하지 않지만 흥미 롭습니다.
Seraphim의

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) }(단일 색상도 a로 래핑됩니다 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.