programacion - manual android studio avanzado
Cambie programáticamente el valor de un recurso de color obtenido de la respuesta API (5)
No puede cambiar los recursos de una aplicación, son todas 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 devolvió, use:
int resourceID = getResources().getIdentifier("green", "color", getPackageName());
Digamos que 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 API?
Como ejemplo:
Hago una llamada a mi API y se vuelve
green
, ahora quiero cargar mi aplicación, es decir (
Toolbar
verde, color verde
TextView
, etc.), ¿es eso posible?
Mi primer pensamiento fue:
Cree un elemento en
colors.xml
llamado
demo
luego asígnele un color predeterminado, luego use este color de
demo
donde quiera (
Button
,
TextView
, etc.) Luego pensé que podría ser posible cambiar este valor mediante programación con el resultado de la API así que no necesitaría crear un
SharedPreferences
o algo así y evitar más código.
Como @Y.S. me dijo
Desafortunadamente, tendrá que establecer el color del texto o verlo manualmente en todas partes ... :(
Me gustaría si hay otra forma de hacerlo, ya que no sé cuántas
Activities
contendrá mi proyecto, así que si hay otra forma de hacerlo, me alegra escuchar otras suposiciones.
EDITAR
Estoy probando la respuesta de @Jared Rummler y tal vez estoy haciendo algo mal ...
Json
un
Json
simple y puse mis Activos,
Json
el
Json
y lo puse en una
GlobalConstant
luego hice un "simple aplicación ".
En primer lugar, tengo un
TextView
y un
Button
que contiene el "your_special_color", y al devolverlo pongo el
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));
No se supone que la clase
R
se edite.
Simplemente contiene referencias a sus recursos.
Deberá configurarlo manualmente. Sin embargo, para reducir la carga de configurarlo manualmente, puede intentar usar bibliotecas especiales para guardar preferencias, por ejemplo:
- Saber - https://github.com/jug6ernaut/saber
- PreferenceBinder - https://github.com/denley/preferencebinder
(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 que desea agregar algunos otros parámetros como altura, ancho, etc. Para ese propósito, puede definir un atributo personalizado en themes.xml / styles.xml:
<attr name="demoColor" format="reference|color" />
luego defina estilos:
<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>
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 ser menos código y más fácil de refactorizar en el futuro. (Aún deberá 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 usar variantes / sabores de compilación para cargar su aplicación con diferentes colores y estilos (es para el tiempo de compilación, no el tiempo de ejecución):
app / src / main / res / colors.xml
<resources>
<color name="demoColor">#00cd00</color>
</resources>
app / src / buildVariant / res / colors.xml
<resources>
<color name="demoColor">#ff0000</color>
</resources>
Ahora puede cambiar rápidamente entre "main" y "buildVariant" en el menú Build Variants e iniciar su aplicación con diferentes colores "demo". De la misma manera, puede personalizar muchos otros atributos.
Busque "Build Variants" aquí http://developer.android.com/tools/building/configuring-gradle.html
Puede crear una clase que amplíe
Resources
y anule los métodos
getColor(int)
y
getColor(int, Theme)
.
Ejemplo:
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;
}
...
}
Este es el enfoque que he usado en una de mis aplicaciones,
Root Check
.
Si anula
getResources
en sus actividades y en la clase de aplicación principal, puede cambiar el tema mediante programación (aunque los temas sean inmutables).
Si lo desea, descargue la aplicación y vea cómo puede establecer los colores primarios, de acento y de fondo desde las preferencias.
Si echa un vistazo al documento Acceso a recursos , lo que dice es que ...
Una vez que proporcione 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 herramientaaapt
genera automáticamente.
Además,
Cuando se compila su aplicación,
aapt
genera la claseR
, que contiene ID de recursos para todos los recursos en su directoriores/
. Para cada tipo de recurso, hay una subclaseR
(por ejemplo,R.drawable
para todos los recursos extraíbles), y para cada recurso de ese tipo, hay un número entero estático (por ejemplo,R.drawable.icon
). Este entero es el ID de recurso que puede usar para recuperar su recurso.
Lo que esto está diciendo, esencialmente, es que casi todo lo que se mantiene como un
recurso
en el directorio
res/
se compila y se hace referencia a él como una constante inmutable.
Es por esta razón que los valores de los elementos de recursos no se pueden cambiar mediante programación / en tiempo de ejecución, ya que se
compilan
.
A diferencia de las variables locales / globales y las
SharedPreferences
, los elementos de recursos se representan en la memoria del programa como objetos fijos e inmutables.
Se mantienen en una región especial de solo lectura de la memoria del programa.
En este sentido, vea también
Cambio de valor de R.String Programmatic
.
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
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 alguna utilidad para ti, échale un vistazo ...
almacenar códigos de color hexadecimales en preferencias compartidas y luego usar la función parsecolor almacenar todos los códigos hexadecimales de colores en sesiones como una cadena y cada vez que desee cambiar el color del botón perticular, vista de texto ... solo recupere ese código de color de la sesión y úselo
por ej.
session.setString("white","#FFFFFF"); String colorname=session.getString("white");yourtextview.setBackgroundColor(Color.parseColor(colorname);