web-dev-qa-db-ja.com

API応答から取得した色リソースの値をプログラムで変更する

たとえば、API呼び出しで、colorというパラメーターがあります。既存のR.colors.colorを編集または変更して、APIの結果から色を割り当てることは可能ですか?

例として:

APIを呼び出してgreenを返します。アプリにi.e(緑色Toolbar、緑色TextView色など)をロードしたいのですが、それは可能ですか?

私の最初の考えは:

colors.xmldemoという名前のアイテムを作成し、デフォルトの色を割り当ててから、このdemo色を好きな場所で使用します(ButtonTextViewなど)その後、APIからの結果を使用してこの値をプログラムで変更することができると考えたため、SharedPreferencesなどを作成する必要がなくなり、コードを追加する必要がなくなりました。

@ Y.S。 私に言ったように

残念ながら、テキストの色を設定するか、どこでも手動で表示する必要があります... :(

プロジェクトに含まれるActivitiesの数がわからないため、他の方法があればいいのですが、他の方法があれば他の推測を聞いてうれしいです。

編集

私は@Jared Rummlerの答えを試していますが、おそらく間違っています...簡単なJsonを作成し、Jsonを解析して自分のアセットを追加しましたGlobalConstantその後、「シンプルなアプリ」を作成しました。

まず第一に、「your_special_color」を含むTextViewButtonがあり、その戻り値としてGlobalConstant intを次のように配置します。

case "your_special_color":                
            return GlobalConstant.color; 

それから私が試したのは、私の最初のActivityには1 TextViewと1 Buttonがあり、前に言ったように、「your_special_color」という色は変更したくないのですが、 IntentButtonがあり、同じものを含むがGlobalConstant.colorを含む他のActivityを開き、変更しません。

私はこれをやってみました(私の2番目のアクティビティ):

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));
71
Skizo-ozᴉʞS

Accessing Resources ドキュメントを見ると、それは...

アプリケーションでリソースを提供したら、そのリソースIDを参照してリソースを適用できます。すべてのリソースIDは、プロジェクトのRクラスで定義され、aaptツールが自動的に生成します。

さらに、

アプリケーションがcompiledの場合、aaptRクラスを生成します。このクラスには、res/のすべてのリソースのリソースIDが含まれますディレクトリ。リソースのタイプごとに、Rサブクラス(すべての描画可能リソースのR.drawableなど)があり、そのタイプのリソースごとに、静的整数(R.drawable.iconなど)があります。この整数は、リソースを取得するために使用できるリソースIDです。

これが本質的に言っているのは、res/ディレクトリでresourceとして保持されているほとんどすべてがコンパイルされ、変更不可能な定数として参照されるということです。このため、リソース要素の値はcompiledであるため、プログラム/実行時に変更できません。ローカル/グローバル変数およびSharedPreferencesとは対照的に、リソース要素はプログラムメモリ内で固定の変更不可能なオブジェクトとして表されます。これらは、プログラムメモリの特別な読み取り専用領域に保持されます。これに関しては、 プログラムでR.Stringの値を変更する も参照してください。

あなたがcanすることは、プロジェクトの千箇所で同じコードを使用することを避けるために、SharedPreferencesの色の値を変更する共通の関数を作成することです。どこでもこのメソッドを使用します。もちろん、あなたはすでにこれを知っていたと確信しています。

プロジェクトに追加する必要のあるコードの量を減らすには、別の方法があります。以前に 書道ライブラリ を使用していたため、アプリ全体でフォントのスタイルと色を修正できました。これはあなたにとっていくつかの有用なものかもしれません、それをチェックしてください...

26
Y.S

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;
    }

    ...

}

これは、アプリの1つ ルートチェック で使用したアプローチです。アクティビティおよびメインアプリケーションクラスでgetResourcesをオーバーライドすると、テーマを不変であっても、プログラムでテーマを変更できます。必要に応じて、アプリをダウンロードして、基本設定、アクセント、および背景色の設定方法を確認してください。

58
Jared Rummler

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" ...

Activity.onCreateGreenActivityスタイルとRedActivityスタイルを切り替える:

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

上記のアプローチを使用すると、スタイルをXMLで簡単に構成でき、コードが少なくなり、将来リファクタリングが容易になります。 (緑または赤のスタイルを保存するために、1つの変数を設定する必要があります)


別の方法として、異なる色でアプリのデモを表示したい場合は、ビルドバリアント/フレーバーを使用してアプリを異なる色とスタイルでロードします(ランタイムではなくビルド時間用です):

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

10
GregoryK

アプリのリソースを変更することはできません。それらはすべて定数です。代わりに、SharedPrefencesに色を保存し、そこから色を使用できます。

AndroidでSharedPreferencesを使用して値を保存、取得、編集する方法 を参照してください。

アプリにR.color.greenが既に定義されていて、返されたAPIに基づいてアクセスしたい場合:

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

16進数のカラーコードをsharedpreferencesに保存し、次にparsecolor関数を使用して、すべての16進数のコードを文字列としてセッションに保存し、特定のボタンの色を変更したいときはいつでも、textview ..
例.
session.setString("white","#FFFFFF"); String colorname=session.getString("white");yourtextview.setBackgroundColor(Color.parseColor(colorname);

3