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));
Android TextView – Text Color. TextView Text Color – To change the color of text in TextView, you can set the color in layout XML file using textColor attribute or change the color dynamically in Kotlin file using setTextColor() method.
A ColorStateList is an object you can define in XML that you can apply as a color, but will actually change colors, depending on the state of the View object to which it is applied.
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.
If you take a look at the Accessing Resources document, what it says is that ...
Once you provide a resource in your application, you can apply it by referencing its resource ID. All resource IDs are defined in your project's
R
class, which theaapt
tool automatically generates.
Furthermore,
When your application is compiled,
aapt
generates theR
class, which contains resource IDs for all the resources in yourres/
directory. For each type of resource, there is anR
subclass (for example,R.drawable
for all drawable resources), and for each resource of that type, there is a static integer (for example,R.drawable.icon
). This integer is the resource ID that you can use to retrieve your resource.
What this is saying, essentially, is that pretty much everything held as a resource in the res/
directory is compiled and referenced as an unchangeable constant. It is for this reason that the values of resource elements cannot be changed programmatically/at runtime, because they are compiled. As opposed to local/global variables & SharedPreferences
, resource elements are represented in program memory as fixed, unchangeable objects. They are held in a special read-only region of program memory. In this regard, see also Changing value of R.String Programmatically.
What you can do is, to avoid using the same code at a thousand places in your project, create a common function that changes the value of the color in the SharedPreferences
and use this method everywhere. I'm sure you knew this already, of course.
To reduce the amount of code you need to add to the project, there is an alternative. I have previously used the calligraphy library which allowed me to fix the font style & color throughout the app. This may be of some good use to you, check it out ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With