以编程方式更改从API响应获得的颜色资源的值

Ski*_*ᴉʞS 73 android aapt android-resources

比方说,在我的API调用中,我有一个被调用的参数color.是否可以编辑或修改现有的R.colors.color以从API结果中分配颜色?

举个例子:

我打电话给我的API并返回green,现在我想用ie(绿色Toolbar,绿色TextView等)加载我的应用程序,这可能吗?

我的第一个想法是:

colors.xml被调用上创建一个项目,demo然后为它指定一个默认颜色,然后demo在我想要的任何地方使用这个颜色(Button,TextView等等)然后我认为可以用API的结果以编程方式更改这个值,所以我不需要创建一个SharedPreferences或类似的东西,以避免更多的代码.

正如@YS对我说的那样

不幸的是,你必须手动设置文本或视图的颜色...... :(

我想如果有其他方法可以做到这一点,因为我不知道Activities我的项目将包含多少,所以如果有其他方法可以做到这一点我很高兴听到其他猜测.

编辑

我正在尝试@Jared Rummler的答案,也许我做错了什么......我创造了一个简单的Json,我把我的资产我解析了Json,我把它放在一个GlobalConstant然后我做了一个"简单的应用程序".

首先,我有一个TextView和a Button包含"your_special_color",并返回它我把GlobalConstant int如下:

case "your_special_color":                
            return GlobalConstant.color; 
Run Code Online (Sandbox Code Playgroud)

然后我尝试的是我的第一个Activity有1 TextView和1,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);
}
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

哦..我想出来我猜我在做这个MainActivity2吗?

 Button btn = (Button)findViewById(R.id.button2);
 btn.setBackgroundColor(res.getColor(R.color.your_special_color));
Run Code Online (Sandbox Code Playgroud)

Jar*_*ler 60

您可以创建延伸类Resources和重写方法getColor(int)getColor(int, Theme).

例:

colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="your_special_color">#FF0099CC</color>
</resources>
Run Code Online (Sandbox Code Playgroud)

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

BaseActivity.java

public class BaseActivity extends AppCompatActivity {

    ...

    private Res res;

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

    ...

}
Run Code Online (Sandbox Code Playgroud)

这是我在我的一个应用程序Root Check中使用的方法.如果getResources在活动和主应用程序类中覆盖,则可以以编程方式更改主题(即使主题是不可变的).如果需要,请下载该应用程序,并查看如何根据首选项设置主要,重音和背景颜色.

  • 对不起,伙计们,但现在这已经是"DEPECRATED"了 (8认同)
  • 我再也不会有6个小时了.随时给我发电子邮件,我会帮助你.jared.rummler@gmail.com (3认同)
  • 我编写了一个库,该库可以动态更改应用程序的背景色,原色和强调色。图书馆目前尚未开放,但希望我能尽快分享。上面的代码在Android 6.0+上不起作用,因为对资源进行了许多更改。另外,我不再拥有答案中链接的“ Root Check”应用程序。 (2认同)

Y.S*_*Y.S 26

如果您查看" 访问资源"文档,它说的是......

在应用程序中提供资源后,可以通过引用其资源ID来应用它.所有资源ID都在项目的R类中定义,aapt工具会自动生成.

此外,

编译应用程序时,aapt生成R类,其中包含res/ 目录中所有资源的资源ID .对于每种类型的资源,都有一个R子类(例如,R.drawable对于所有可绘制资源),并且对于该类型的每个资源,都有一个静态整数(例如, R.drawable.icon).此整数是可用于检索资源的资源ID.

实质上,这就是说,作为目录中的资源而保存的所有内容都res/被编译并作为不可更改的常量引用.出于这个原因,资源元素的值不能以编程方式/在运行时更改,因为它们是编译的.与本地/全局变量&相反SharedPreferences,资源元素在程序存储器中表示为固定的,不可更改的对象.它们保存在程序存储器的特殊只读区域中.在这方面,请参阅以编程方式更改R.String的值.

可以做的是,为了避免在项目的一千个地方使用相同的代码,创建一个改变颜色值的常用函数,SharedPreferences并在任何地方使用此方法.当然,我确定你已经知道了.

为了减少需要添加到项目中的代码量,还有一种替代方法.我之前使用的书法库让我可以在整个应用程序中修复字体样式和颜色.这可能对你有好处,请查看...


Sou*_*abh 10

您无法更改应用程序的资源,它们都是常量.相反,您可以在SharedPrefences中保存颜色并使用那里的颜色.

请参阅如何在Android中使用SharedPreferences来存储,获取和编辑值.

如果您的应用已经定义了R.color.green,并且您只是想根据您使用的API返回来访问它:

int resourceID = getResources().getIdentifier("green", "color", getPackageName());
Run Code Online (Sandbox Code Playgroud)


Gre*_*ryK 10

Rclass不应该被编辑.它只包含对您资源的引用.

您需要手动设置它.但是,为了减少手动设置它的负担,您可以尝试使用特殊库来保存首选项,例如:

(类似库的完整列表https://android-arsenal.com/tag/75)


此外,您可能想要考虑应用样式和传递参数的另一种方法 - 考虑您要添加一些其他参数,如高度,宽度等.为此,您可以在themes.xml/styles.xml中定义自定义属性:

<attr name="demoColor" format="reference|color" />
Run Code Online (Sandbox Code Playgroud)

然后定义样式:

<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>
Run Code Online (Sandbox Code Playgroud)

然后在你的xml中使用这种颜色,如下所示:

... android:background="?demoColor" ...
Run Code Online (Sandbox Code Playgroud)

并切换GreenActivityRedActivity样式Activity.onCreate:

setTheme(isGreenStyle() ? R.style.GreenActivity : R.style.RedActivity)
setContentView(...)
Run Code Online (Sandbox Code Playgroud)

使用上述方法,您将能够在xml中轻松配置样式,并且应该是更少的代码,并且将来更容易重构.(您仍然需要优先选择一个变量来保存您是否有绿色或红色样式)


另一种方式,如果你想用不同的颜色显示你的应用程序的演示是使用构建变体/口味来加载你的应用程序与不同的颜色和样式(它是为了构建时间 - 而不是运行时):

应用程序/ SRC /主/ RES/colors.xml

<resources>
    <color name="demoColor">#00cd00</color>
</resources>
Run Code Online (Sandbox Code Playgroud)

应用程序/ src目录/ buildVariant/RES/colors.xml

<resources>
    <color name="demoColor">#ff0000</color>
</resources>
Run Code Online (Sandbox Code Playgroud)

现在,您可以在Build Variants菜单中快速切换"main"和"buildVariant",并使用不同的"演示"颜色启动您的应用程序.您可以使用相同的方式自定义许多其他属性.

在这里搜索"Build Variants" http://developer.android.com/tools/building/configuring-gradle.html


归档时间:

查看次数:

48298 次

最近记录:

8 年,6 月 前