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

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



답변

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

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

더욱이,

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

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

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

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


답변

당신은 확장하는 클래스를 만들 수 있습니다 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활동 및 기본 애플리케이션 클래스에서 재정의 하면 테마를 변경할 수 없더라도 프로그래밍 방식으로 테마를 변경할 수 있습니다. 원하는 경우 앱을 다운로드하고 기본 설정에서 기본, 강조 및 배경 색상을 설정하는 방법을 확인하십시오.


답변

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 에서 “빌드 변형”을 검색합니다.


답변

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

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

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

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


답변

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


답변