Let's say, on my API call I have a parameter that's called color
. Is it possible to edit or modify an existent R.colors.color
to assign the color from the API result?
As an example:
I make a call to my API and it returns green
, now I want to load my app with i.e (green Toolbar
, green TextView
color, etc.), is that possible?
My first thought was:
Create a item on colors.xml
called demo
then assign it a default color, then use this demo
color wherever I want (Button
, TextView
, etc.) Then I thought it could be possible to change this value programmatically with the result from the API so I wouldn't need to create a SharedPreferences
or something like that and for avoiding more code.
As @Y.S. said to me
Unfortunately, you WILL have to set the color of the text or view manually everywhere ... :(
I would like if there is other way to do it, since I don't know how many Activities
my project will contain, so if is there other way to do it I'm glad to hear other guesses.
I'm trying the @Jared Rummler answer and maybe i'm doing something wrong... I've created a simple Json
and I put on my Assets I parse the Json
and I put it on a GlobalConstant
then I made a "simple app".
First of all I have a TextView
and a Button
which contains the "your_special_color", and the return of it I put the GlobalConstant int
as follows :
case "your_special_color":
return GlobalConstant.color;
Then what I tried is my first Activity
has 1 TextView
and 1 Button
as I said before and they have the color "your_special_color" that I don't want to change it, BUT I have an Intent
on my Button
to open the other Activity
that contains the same but with the GlobalConstant.color
and it doesn't change.
I tried it doing this (my second Activity):
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);
}
Did I miss something?
Oh.. I figured it out I guess is doing this on my MainActivity2
?
Button btn = (Button)findViewById(R.id.button2);
btn.setBackgroundColor(res.getColor(R.color.your_special_color));
You can create a class which extends Resources
and override the methods getColor(int)
and 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;
}
...
}
This is the approach I have used in one of my apps, Root Check. If you override getResources
in your activities and main application class you can change the theme programmatically (even though themes are immutable). If you want, download the app and see how you can set the primary, accent, and background colors from preferences.