以编程方式更改从API响应获取的颜色资源的值
比方说,在我的API调用中,我有一个叫做color
的参数。 是否可以编辑或修改现有的R.colors.color
来从API结果中分配颜色?
举个例子:
我打电话给我的API,它返回green
,现在我想加载我的应用程序与ie(绿色Toolbar
,绿色TextView
颜色等),这可能吗?
我的第一个想法是:
在colors.xml
创build一个名为demo
的项目,然后为其分配一个默认的颜色,然后使用这个demo
颜色( Button
, TextView
等等)。然后我认为可以用API的结果以编程方式改变这个值所以我不需要创build一个SharedPreferences
或类似的东西,并避免更多的代码。
@YS对我说
不幸的是,你将不得不手动设置文本或视图的颜色… 🙁
我想如果还有其他方法可以做到这一点,我不知道我的项目将包含多lessActivities
,所以如果有其他方法可以做到这一点,我很高兴听到其他的猜测。
编辑
我正在尝试@Jared Rummler的答案,也许我做错了什么…我创build了一个简单的Json
,我把我的资产我parsingJson
,我把它放在一个GlobalConstant
然后我做了一个“简单应用”。
首先我有一个TextView
和一个Button
,其中包含“your_special_color”,并返回它我把GlobalConstant int
如下所示:
case "your_special_color": return GlobalConstant.color;
然后,我尝试的是我的第一个Activity
有1个TextView
和1个Button
正如我之前所说,他们有颜色“your_special_color”,我不想改变它,但我有我的Button
的Intent
打开其他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
工具会自动生成。
此外,
在编译应用程序时,
aapt
生成R
类,其中包含res/
目录中所有资源的资源ID。 对于每种types的资源,都有一个R
子类(例如,对所有可绘制资源使用了R.drawable
),并且对于该types的每个资源,都有一个静态整数(例如,R.drawable.icon
)。 此整数是您可以用来检索资源的资源ID。
这实际上是说, res/
目录中的所有res/
被编译并引用为不可更改的常量。 正是由于这个原因,资源元素的值不能在运行时以编程方式改变,因为它们被编译 。 与本地/全局variables& SharedPreferences
相反,资源元素在程序存储器中表示为固定的,不可更改的对象。 它们被保存在程序存储器的特殊只读区域中。 在这方面,请参阅以编程方式更改R.String的值 。
你可以做的是,为了避免在你的项目的一千个地方使用相同的代码,创build一个通用的函数来改变SharedPreferences
中的颜色的值,并在任何地方使用这个方法。 当然,我确定你已经知道了。
为了减less需要添加到项目中的代码量,还有一个select。 我以前使用的书法库允许我在整个应用程序中修复字体样式和颜色。 这可能对你有一些很好的用处,检查出来…
您可以创build一个扩展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
类不应被编辑。 它仅包含对您的资源的引用。
您将需要手动设置。 但是,为了减轻手动设置的负担,您可以尝试使用特殊库来保存偏好,例如:
- Sabre – https://github.com/jug6ernaut/saber
- PreferenceBinder – https://github.com/denley/preferencebinder
(类似图书馆的完整列表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.onCreate
GreenActivity
和RedActivity
样式之间切换:
setTheme(isGreenStyle() ? R.style.GreenActivity : R.style.RedActivity) setContentView(...)
通过上述方法,您将能够轻松地在xml中configuration自己的样式,并且应该是更less的代码,并且更容易在将来进行重构。 (你仍然需要有一个variables,以保存你是否有绿色或红色的风格)
另一种方式,如果你想用不同的颜色来展示你的应用程序的演示,就是使用不同的颜色和样式来加载你的应用程序的构build变体/风格(这是build立时间 – 而不是运行时):
应用程序/ SRC /主/ RES / colors.xml
<resources> <color name="demoColor">#00cd00</color> </resources>
应用程序/ src目录/ buildVariant / RES / colors.xml
<resources> <color name="demoColor">#ff0000</color> </resources>
现在,您可以在Build Variants菜单中快速切换“main”和“buildVariant”,并以不同的“演示”颜色启动应用程序。 用同样的方法可以定制很多其他的属性。
在这里search“Build Variants” http://developer.android.com/tools/building/configuring-gradle.html
你不能改变一个应用程序的资源,它们都是常量。 相反,您可以将您的颜色保存在SharedPrefences中,并使用此颜色。
请参阅如何在Android中使用SharedPreferences来存储,获取和编辑值 。
如果您的应用程序已经定义了一个R.color.green,并且您只是想根据您返回的API使用它:
int resourceID = getResources().getIdentifier("green", "color", getPackageName());
将hex颜色代码存储到sharedpreferences中,然后使用parsecolor函数将所有颜色的hex代码以string的forms存储到会话中,并且只要要更改相关button的颜色,textview..just就可以从会话中取回颜色代码,并将其用作
例如。
session.setString("white","#FFFFFF"); String colorname=session.getString("white");yourtextview.setBackgroundColor(Color.parseColor(colorname);