Cambia programáticamente el valor de un recurso de color obtenido de la respuesta de API

Digamos, en mi llamada API tengo un parámetro que se llama color . ¿Es posible editar o modificar un R.colors.color existente para asignar el color del resultado de la API?

Como ejemplo:

Hago una llamada a mi API y vuelve green , ahora quiero cargar mi aplicación con ie ( Toolbar verde, color verde de TextView , etc.), ¿es eso posible?

Mi primer pensamiento fue:

Cree un artículo en colors.xml llamado demo y asígnele un color predeterminado, luego use este color de demo donde quiera ( Button , TextView , etc.) Entonces pensé que podría ser posible cambiar este valor programáticamente con el resultado de la API así que no necesitaría crear una SharedPreferences o algo así y para evitar más código.

Como @YS me dijo

Desafortunadamente, tendrá que establecer el color del texto o verlo manualmente en todas partes … 🙁

Me gustaría si hay otra manera de hacerlo, ya que no sé cuántas Activities contendrá mi proyecto, así que si hay otra forma de hacerlo, me alegra escuchar otras conjeturas.

EDITAR

Estoy probando la respuesta de @Jared Rummler y tal vez estoy haciendo algo mal … He creado un Json simple y me he puesto mis activos. Json el Json y lo puse en un GlobalConstant luego hice un “simple” aplicación “.

En primer lugar, tengo un TextView y un Button que contiene el “your_special_color” y, a su regreso, puse GlobalConstant int siguiente manera:

 case "your_special_color": return GlobalConstant.color; 

Entonces, lo que probé es que mi primera Activity tiene 1 TextView y 1 Button como dije antes y tienen el color “your_special_color” que no quiero cambiar, PERO tengo un Intent en mi Button para abrir la otra Activity que contiene lo mismo pero con GlobalConstant.color y no cambia.

Lo intenté haciendo esto (mi segunda actividad):

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

¿Me he perdido algo?

Oh … lo descubrí, ¿supongo que está haciendo esto en mi MainActivity2 ?

  Button btn = (Button)findViewById(R.id.button2); btn.setBackgroundColor(res.getColor(R.color.your_special_color)); 

Si echas un vistazo al documento de Recursos de acceso , lo que dice es que …

Una vez que proporciona un recurso en su aplicación, puede aplicarlo haciendo referencia a su ID de recurso. Todos los ID de recursos se definen en la clase R su proyecto, que la herramienta aapt genera automáticamente.

Además,

Cuando se comstack su aplicación, aapt genera la clase R , que contiene ID de recursos para todos los recursos en su directorio res/ . Para cada tipo de recurso, hay una subclase R (por ejemplo, R.drawable para todos los recursos R.drawable ), y para cada recurso de ese tipo, hay un entero estático (por ejemplo, R.drawable.icon ). Este entero es la ID del recurso que puede usar para recuperar su recurso.

Lo que esto dice, esencialmente, es que prácticamente todo lo que se retiene como un recurso en el directorio res/ se comstack y se hace referencia como una constante inmutable. Es por esta razón que los valores de los elementos de recursos no se pueden cambiar programáticamente / en tiempo de ejecución, porque se comstackn . A diferencia de las variables locales / globales y las SharedPreferences , los elementos de recursos se representan en la memoria del progtwig como objetos fijos e inmutables. Se mantienen en una región especial de solo lectura de la memoria del progtwig. En este sentido, consulte también Cambiar el valor de R.String mediante progtwigción .

Lo que puede hacer es evitar el uso del mismo código en miles de lugares en su proyecto, crear una función común que cambie el valor del color en las SharedPreferences y usar este método en todas partes. Estoy seguro de que ya lo sabías, por supuesto.

Para reducir la cantidad de código que necesita agregar al proyecto, existe una alternativa. Anteriormente utilicé la biblioteca de caligrafía, que me permitió corregir el estilo y el color de la fuente en toda la aplicación. Esto puede ser de gran utilidad para ti, compruébalo …

Puede crear una clase que amplíe Resources y anule los métodos getColor(int) y getColor(int, Theme) .

Ejemplo:

colors.xml

   #FF0099CC  

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

Este es el enfoque que he utilizado en una de mis aplicaciones, Root Check . Si anula getResources en sus actividades y clase de aplicación principal, puede cambiar el tema mediante progtwigción (incluso si los temas son inmutables). Si lo desea, descargue la aplicación y vea cómo puede establecer los colores primarios, de acento y de fondo de las preferencias.

Se supone que la clase R no debe editarse. Simplemente contiene referencias a tus recursos.

Tendrá que configurarlo manualmente. Sin embargo, para reducir la carga de configurarlo manualmente, puede intentar usar bibliotecas especiales para guardar las preferencias, por ejemplo:

(lista completa de bibliotecas similares https://android-arsenal.com/tag/75 )


Además, es posible que desee pensar en otra forma de aplicar estilos y pasar parámetros; considere la posibilidad de agregar otros parámetros como alto, ancho, etc. Para ello, puede definir un atributo personalizado en themes.xml / styles.xml:

  

luego define estilos:

    

luego usa ese color en tu xml así:

 ... android:background="?demoColor" ... 

y cambie entre los estilos GreenActivity y RedActivity en Activity.onCreate :

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

Con el enfoque anterior, podrá configurar fácilmente sus estilos en xml y debería tener menos código y ser más fácil de refactorizar en el futuro. (Aún necesitará tener una variable de preferencia para guardar si tiene un estilo verde o rojo)


Otra forma, si desea mostrar demostraciones de su aplicación con diferentes colores, es utilizar variantes / sabores de comstackción para cargar su aplicación con diferentes colores y estilos (es para el tiempo de comstackción, no para el tiempo de ejecución):

app / src / main / res / colors.xml

  #00cd00  

app / src / buildVariant / res / colors.xml

  #ff0000  

Ahora puede cambiar rápidamente entre “principal” y “buildVariant” en el menú Variantes de comstackción y ejecutar su aplicación con diferentes colores de “demostración”. De la misma manera puedes personalizar muchos otros atributos.

Busque “Variantes de comstackción” aquí http://developer.android.com/tools/building/configuring-gradle.html

No puede cambiar los recursos de una aplicación, todos son constantes. En su lugar, puede guardar su color en SharedPrefences y usar el color desde allí.

Consulte Cómo usar SharedPreferences en Android para almacenar, recuperar y editar valores .

Si su aplicación ya tiene un R.color.green definido y solo desea acceder a él en función de la API que haya devuelto, utilice:

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

almacene los códigos de color hexadecimal en las preferencias compartidas y luego use la función parsecolor almacene todos sus códigos hexadecimales de colores en una cadena y cuando quiera cambiar el color del botón perticular, vista de texto … simplemente recupere ese código de color de la sesión y úselo como
por ej.
session.setString("white","#FFFFFF"); String colorname=session.getString("white");yourtextview.setBackgroundColor(Color.parseColor(colorname);