API 응답에서 얻은 색상 리소스의 값을 프로그래밍 방식으로 변경


80

내 API 호출에라는 매개 변수가 있다고 가정 해 보겠습니다 color. R.colors.colorAPI 결과에서 색상을 할당하기 위해 존재를 편집하거나 수정할 수 있습니까?

예로서:

내 API를 호출하면을 반환합니다 green. 이제 내 앱을 (녹색 Toolbar, 녹색 TextView등) 로드하고 싶습니다 . 가능합니까?

내 첫 생각은 :

에 항목을 만들기 colors.xml라는 demo이 사용 후, 그것을 기본 색을 지정 다음을 demo내가 원하는 목적지 색상을 ( Button, TextView, 등) 그런 다음 내가 필요하지 않을 그래서이 API의 결과로 프로그램이 값을 변경하는 것이 가능할 수 있다고 생각 창조하다SharedPreferences 같은 더 많은 코드를 피하거나 무언가를.

으로 @YS는 나에게 말했다

불행히도 텍스트의 색상을 설정하거나 모든 곳에서 수동으로 볼 수 있습니다 ... :(

Activities내 프로젝트에 얼마나 많이 포함 될지 모르기 때문에 다른 방법이 있으면 좋겠다 . 그래서 다른 방법이 있으면 다른 추측을 듣고 기쁘다.

편집하다

나는 @Jared Rummler 대답을 시도하고 있고 아마도 내가 뭔가 잘못하고있을 것입니다 ... 나는 간단한 Json것을 만들었고 나는 내 자산을 파싱하고 Json그것을GlobalConstant 다음 "간단한 앱"을 만들었다.

우선 나는 "your_special_color"를 포함하는 a TextView와 a Button를 가지고 있으며 그 반환은 GlobalConstant int다음과 같이 넣습니다 .

case "your_special_color":                
            return GlobalConstant.color; 

그럼 내가 노력하는 것은 나의 최초의 Activity1이 TextView1을 Button내가 전에 말했듯이 그들은 색상이 "your_special_color"나는 그것을 변경하지 않습니다,하지만 나는이 것을 Intent내에서 Button다른 여는 Activity동일하지만,과가 포함을 GlobalConstant.color그리고 그것은 변하지 않습니다.

나는 이것을 시도했다 (내 두 번째 활동).

public class Main2Activity extends AppCompatActivity {
private Res res;
@Override public Resources getResources() {
    if (res == null) {
        res = new Res(super.getResources());
    }
    return res;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main2);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
}

내가 뭘 놓 쳤니?

오 .. 내 생각에 이거 알아 MainActivity2?

 Button btn = (Button)findViewById(R.id.button2);
 btn.setBackgroundColor(res.getColor(R.color.your_special_color));

1
그것에 대한 해결책을 얻었습니까?
Tixeon

1
야! 마침내이 문제를 해결 했습니까? 비슷한 문제에 직면하고 있습니다!
Rohitesh

내 생각은 작동 자레드 솔루션에 따라
Skizo-ozᴉʞS

1
동적으로 기본 및 악센트 색상을 변경하는 Cyanea를 체크 아웃 : github.com/jaredrummler/Cyanea
자레드 Rummler

@JaredRummler Cyanea의 작동 원리를 설명하는 게시물을 추가해 주시겠습니까? 감사.
Q Locker

답변:


27

리소스 액세스 문서를 살펴보면 다음과 같습니다 .

애플리케이션에 리소스를 제공하면 리소스 ID를 참조하여 적용 할 수 있습니다. 모든 리소스 ID는 도구가 자동으로 생성 R하는 프로젝트의 클래스에 정의 aapt됩니다.

더욱이,

애플리케이션이 컴파일 되면 디렉토리의 모든 리소스에 대한 리소스 ID가 포함 된 클래스를 aapt생성합니다 . 각 리소스 유형에 대해 하위 클래스 (예 : 모든 드로어 블 리소스)가 있고 해당 유형의 각 리소스에 대해 정적 정수 (예 :)가 있습니다. 이 정수는 리소스를 검색하는 데 사용할 수있는 리소스 ID입니다.Rres/RR.drawableR.drawable.icon

이것이 본질적으로 말하는 것은 디렉토리에 자원 으로 보유 된 거의 모든 res/것이 컴파일되고 변경 불가능한 상수로 참조된다는 것입니다. 이러한 이유로 리소스 요소의 값은 컴파일 되기 때문에 프로그래밍 방식으로 / 런타임에 변경할 수 없습니다 . 로컬 / 글로벌 변수 & SharedPreferences와 달리 자원 요소는 프로그램 메모리에서 변경 불가능한 고정 객체로 표시됩니다. 프로그램 메모리의 특수 읽기 전용 영역에 보관됩니다. 이와 관련하여 프로그래밍 방식으로 R.String 값 변경을 참조하십시오 .

당신이 할 수있는 일은 프로젝트의 천 개 위치에서 동일한 코드를 사용하지 않으려면의 색상 값을 변경하는 공통 함수를 SharedPreferences만들고이 방법을 모든 곳에서 사용하는 것입니다. 물론 이미 알고 계실 겁니다.

프로젝트에 추가해야하는 코드의 양을 줄이기위한 대안이 있습니다. 이전 에 앱 전체에서 글꼴 스타일과 색상을 수정할 수 있는 서예 라이브러리 를 사용했습니다 . 이것은 당신에게 유용 할 수 있습니다.


그러니 그렇게 할 수 없다는 말이군요 ...? 그런 다음 각 활동의 각 조각에보기에 대한 색상을 만들어야합니까?
Skizo-ozᴉʞS 2015

맞습니다, 당신은 그렇게 할 수 없습니다. 그러나 색상을 반복적으로 생성 할 필요는 없습니다. 공통 기본 클래스에서 색상을 생성하고 값을 어디서나 사용할 수있는 전역 변수로 유지할 수 있습니다. 불행하게도, 당신은 :( ... 수동으로 모든 곳에서 텍스트 또는 뷰의 색상을 설정해야합니다
YS

예, 제가 의미하는 바는 ... sharedpref에 값을 저장 한 다음 글로벌 클레스를 만들어 색상을 선언 할 수 있지만 ... 모든 setcolor 설정된 배경이 잘 필요합니다 ... 다음과 같은 경우 어딘가에서 다른 솔루션을 찾으려고합니다. @YS
Skizo-ozᴉʞS

de api에서 이것을 사용하면 글꼴도 얻을 수 있습니까?
Skizo-ozᴉʞS 2015

앱에 글꼴을 할당 한 다음 색상을 선언 할 수 있다는 뜻입니까?
Skizo-ozᴉʞS 2015

70

당신은 확장하는 클래스를 만들 수 있습니다 Resources및 방법을 무시 getColor(int)하고getColor(int, Theme) .

예:

colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="your_special_color">#FF0099CC</color>
</resources>

Res.java

public class Res extends Resources {

    public Res(Resources original) {
        super(original.getAssets(), original.getDisplayMetrics(), original.getConfiguration());
    }

    @Override public int getColor(int id) throws NotFoundException {
        return getColor(id, null);
    }

    @Override public int getColor(int id, Theme theme) throws NotFoundException {
        switch (getResourceEntryName(id)) {
            case "your_special_color":
                // You can change the return value to an instance field that loads from SharedPreferences.
                return Color.RED; // used as an example. Change as needed.
            default:
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    return super.getColor(id, theme);
                }
                return super.getColor(id);
        }
    }
}

BaseActivity.java

public class BaseActivity extends AppCompatActivity {

    ...

    private Res res;

    @Override public Resources getResources() {
        if (res == null) {
            res = new Res(super.getResources());
        }
        return res;
    }

    ...

}

이것은 내 앱 중 하나 인 Root Check 에서 사용한 접근 방식 입니다. getResources활동 및 기본 애플리케이션 클래스에서 재정의 하면 테마를 변경할 수 없더라도 프로그래밍 방식으로 테마를 변경할 수 있습니다. 원하는 경우 앱을 다운로드하고 기본 설정에서 기본, 강조 및 배경 색상을 설정하는 방법을 확인하십시오.


답변 해주셔서 감사합니다! 나는 그것을주의 깊게 읽고 그것이 내가 필요한지 확인하려고 노력할 것입니다. 이것으로 API 호출에서 색상 (int)을 얻고 모든 배경, 스타일 등에 사용하면 생각합니다 ... 기본 색상 API의 색상이 표시됩니까?
Skizo-ozᴉʞS

3
6 시간 더 사용할 수 없습니다. 저에게 이메일을 보내 주시면 도와 드리겠습니다. jared.rummler@gmail.com
Jared Rummler

9
미안 얘들 아, 그러나 이것은 지금DEPECRATED
Arav K.

1
getColor에서 (INT, 테마)를 호출하지
학습자

2
앱의 배경색, 기본 색, 강조 색을 동적으로 변경하는 라이브러리를 작성했습니다. 라이브러리는 현재 열려 있지 않지만 곧 공유 할 수 있기를 바랍니다. 위의 코드는 리소스가 많이 변경 되었기 때문에 Android 6.0 이상에서는 작동하지 않습니다. 또한 나는 더 이상 답변에 연결된 Root Check 앱을 소유하지 않습니다.
Jared Rummler

13

R클래스는 편집 할 수 없습니다. 리소스에 대한 참조 만 포함합니다.

수동으로 설정해야합니다. 그러나 수동으로 설정하는 부담을 줄이려면 환경 설정 저장을 위해 특수 라이브러리를 사용할 수 있습니다. 예를 들면 다음과 같습니다.

(유사 라이브러리의 전체 목록 https://android-arsenal.com/tag/75 )


또한 스타일을 적용하고 매개 변수를 전달하는 다른 방법에 대해 생각하고 싶을 수 있습니다. 높이, 너비 등과 같은 다른 매개 변수를 추가 할 수도 있습니다.이를 위해 themes.xml / styles.xml에서 사용자 정의 속성을 정의 할 수 있습니다.

<attr name="demoColor" format="reference|color" />

그런 다음 스타일을 정의하십시오.

<style name="BaseActivity">
</style>
<style name="GreenActivity" parent="@style/BaseActivity">
    <item name="demoColor">#00cd00</item>
</style>
<style name="RedActivity" parent="@style/BaseActivity">
    <item name="demoColor">#ff0000</item>
</style>

그런 다음 다음과 같이 xml에서 해당 색상을 사용하십시오.

... android:background="?demoColor" ...

에서 GreenActivityRedActivity스타일 사이를 전환 합니다 Activity.onCreate.

setTheme(isGreenStyle() ? R.style.GreenActivity : R.style.RedActivity)
setContentView(...)

위의 접근 방식을 사용하면 xml에서 스타일을 쉽게 구성 할 수 있으며 나중에 코드가 줄어들고 리팩토링하기가 더 쉬워집니다. (녹색 또는 빨간색 스타일을 저장하려면 선호하는 변수가 하나 있어야합니다.)


또 다른 방법은 다른 색상으로 앱의 데모를 표시하려는 경우 빌드 변형 / 향을 사용하여 다양한 색상과 스타일로 앱을로드하는 것입니다 (런타임이 아닌 빌드 시간 용).

app / src / main / res / colors.xml

<resources>
    <color name="demoColor">#00cd00</color>
</resources>

app / src / buildVariant / res / colors.xml

<resources>
    <color name="demoColor">#ff0000</color>
</resources>

이제 Build Variants 메뉴에서 "main"과 "buildVariant"사이를 빠르게 전환하고 다른 "데모"색상으로 앱을 시작할 수 있습니다. 같은 방법으로 많은 다른 속성을 사용자 정의 할 수 있습니다.

http://developer.android.com/tools/building/configuring-gradle.html 에서 "빌드 변형"을 검색합니다.


오 이것에 대해 듣지 못했습니다. 그래서 buildvariant를 사용하면 프로그래밍 방식으로 값을 변경할 수 있습니까?
Skizo-ozᴉʞS

@Skizo 빌드 변형 / 향은 프로그래밍 방식으로 값을 변경하는 것이 아닙니다. 다양한 스타일 / 색상 / 리소스로 앱을 빌드하고 실행할 수 있습니다. 질문에서 "프로그래밍 방식"부분을 놓친 것 같습니다. :) 제 답변을 조금 업데이트하겠습니다. 구현하려는 기능의 실제 사용을 지정할 수 있다면 도움이 될 것입니다. 더 나은 방법이있을 수 있습니다.
GregoryK

스타일이 아닌 색상 만 저장하고 싶습니다.
Skizo-ozᴉʞS dec.

내가 참조. 몇 가지 기본 설정 라이브러리가 추가되었으므로 기본 설정을 바인딩 할 수 있으므로 사용을 고려할 수 있습니다. 이는 코드를 줄이는 데 도움이 될 수 있습니다.
GregoryK

이것이 바로 제가 찾던 것입니다 !!! 너는 천재 야! 레이아웃과 코드에서도 색상을 사용할 수 있습니다. 다음은 코드에서 사용하는 좋은 예입니다. stackoverflow.com/questions/17277618/…
bentzy

10

앱의 리소스는 변경할 수 없으며 모두 상수입니다. 대신 SharedPrefences에 색상을 저장하고 거기에서 색상을 사용할 수 있습니다.

Android에서 SharedPreferences를 사용하여 값을 저장, 가져 오기 및 편집하는 방법을 참조하십시오 .

앱에 이미 R.color.green이 정의되어 있고 반환 된 API에 따라 액세스하려는 경우 다음을 사용합니다.

int resourceID = getResources().getIdentifier("green", "color", getPackageName());

알고 SharedPreferences있지만 이해하지 못한 것 같습니다. colors.xmlright? 라는 파일을 만들 수 있다는 뜻입니다 . 그런 다음 HEX를 사용하여 색상으로 항목을 만든 다음이 값을 프로그래밍 방식으로 수정하여 먼저 데모 색상을 넣은 다음 실제 색상을 넣을 수 있는지 알고 싶습니다.
Skizo-ozᴉʞS 2015

런타임시 colors.xml의 내용을 변경할 수 없습니다. 대신 가능한 모든 색상을 유지하고 getIdentifier를 사용하여 API에서 반환 한 색상을 가져올 수 있습니다. 선택한 색상을 SharedPref에 유지하고 API 호출이 완료 될 때까지 다음 세션에서 나중에 검색 할 수 있습니다.
Sourabh

Ya,하지만 textView 또는 버튼의 textColor를 설정하는 방법은 무엇입니까? 10 개의 Textview가 있고 녹색 텍스트에 배치하려면 각각에 대해 setText (java)를 넣고 SharedPreferences의 값에 서명해야합니까? ...
Skizo-ozᴉʞS

네, 그게 유일한 방법입니다. 게다가 리소스를 변경하면 나중에 앱에서 모든 종류의 혼란을 초래할 수 있습니다
Sourabh

3

16 진수 색상 코드를 sharedpreferences에 저장 한 다음 parsecolor 기능을 사용하여 모든 16 진수 색상 코드를 세션에 문자열로 저장하고 수직 버튼의 색상을 변경하려면 textview .. 세션에서 해당 색상 코드를 검색
하여 예 와 같이 사용하십시오 .
session.setString("white","#FFFFFF"); String colorname=session.getString("white");yourtextview.setBackgroundColor(Color.parseColor(colorname);


그게 뭔데? 코드를 조금 설명 할 수 있습니까?
Skizo-ozᴉʞS
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.