sirve - ¿Cómo_realmente_ cambia programáticamente el color primario y de acento en Android Lollipop?
youtube como medio de comunicacion pdf (10)
En primer lugar, esta pregunta plantea una pregunta muy similar. Sin embargo, mi pregunta tiene una diferencia sutil.
Lo que me gustaría saber es si es posible cambiar programáticamente el atributo colorPrimary
de un tema por un color arbitrario .
Entonces, por ejemplo, tenemos:
<style name="AppTheme" parent="android:Theme.Material.Light">
<item name="android:colorPrimary">#ff0000</item>
<item name="android:colorAccent">#ff0000</item>
</style>
En tiempo de ejecución, el usuario decide que quiere usar #ccffff
como color primario. Por supuesto, no hay forma de que pueda crear temas para todos los colores posibles.
No me importa si tengo que hacer hacky cosas, como confiar en las partes internas privadas de Android, siempre y cuando funcione con el SDK público.
Mi objetivo es eventualmente tener el ActionBar
y todos los widgets como un CheckBox
para usar este color primario.
Esto es lo que puedes hacer:
escriba un archivo en una carpeta dibujable, asígnele el nombre background.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="?attr/colorPrimary"/>
</shape>
luego configura tu diseño (o lo que sea que sea el caso) android:background="@drawable/background"
al configurar su tema, este color representaría lo mismo.
He creado alguna solución para crear temas personalizados de cualquier color, tal vez esto puede ser útil para alguien. API 9+
1. primero crea " res / values-v9 / " y coloca allí este archivo: styles.xml y la styles.xml regular "res / values" se usará con tus estilos.
2. Pon este código en tu res / values / styles.xml:
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light">
<item name="colorPrimary">#000</item>
<item name="colorPrimaryDark">#000</item>
<item name="colorAccent">#000</item>
<item name="android:windowAnimationStyle">@style/WindowAnimationTransition</item>
</style>
<style name="AppThemeDarkActionBar" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">#000</item>
<item name="colorPrimaryDark">#000</item>
<item name="colorAccent">#000</item>
<item name="android:windowAnimationStyle">@style/WindowAnimationTransition</item>
</style>
<style name="WindowAnimationTransition">
<item name="android:windowEnterAnimation">@android:anim/fade_in</item>
<item name="android:windowExitAnimation">@android:anim/fade_out</item>
</style>
</resources>
3. en AndroidManifest:
<application android:theme="@style/AppThemeDarkActionBar">
4. crea una nueva clase con el nombre "ThemeColors.java"
public class ThemeColors {
private static final String NAME = "ThemeColors", KEY = "color";
@ColorInt
public int color;
public ThemeColors(Context context) {
SharedPreferences sharedPreferences = context.getSharedPreferences(NAME, Context.MODE_PRIVATE);
String stringColor = sharedPreferences.getString(KEY, "004bff");
color = Color.parseColor("#" + stringColor);
if (isLightActionBar()) context.setTheme(R.style.AppTheme);
context.setTheme(context.getResources().getIdentifier("T_" + stringColor, "style", context.getPackageName()));
}
public static void setNewThemeColor(Activity activity, int red, int green, int blue) {
int colorStep = 15;
red = Math.round(red / colorStep) * colorStep;
green = Math.round(green / colorStep) * colorStep;
blue = Math.round(blue / colorStep) * colorStep;
String stringColor = Integer.toHexString(Color.rgb(red, green, blue)).substring(2);
SharedPreferences.Editor editor = activity.getSharedPreferences(NAME, Context.MODE_PRIVATE).edit();
editor.putString(KEY, stringColor);
editor.apply();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) activity.recreate();
else {
Intent i = activity.getPackageManager().getLaunchIntentForPackage(activity.getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
activity.startActivity(i);
}
}
private boolean isLightActionBar() {// Checking if title text color will be black
int rgb = (Color.red(color) + Color.green(color) + Color.blue(color)) / 3;
return rgb > 210;
}
}
5. y antes de llamar a setContentView (R.layout.activity_main) , solo agregue:
new ThemeColors(this);
para cambiar el color, reemplace Aleatorio con su RGB:
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int red= new Random().nextInt(255);
int green= new Random().nextInt(255);
int blue= new Random().nextInt(255);
ThemeColors.setNewThemeColor(MainActivity.this, red, green, blue);
}
});
La biblioteca GreenMatter puede ayudarlo a lograr la funcionalidad que está buscando:
Leí los comentarios sobre la aplicación de contactos y cómo usa un tema para cada contacto.
Probablemente, la aplicación de contactos tiene algunos temas predefinidos (para cada color principal de material desde aquí: http://www.google.com/design/spec/style/color.html ).
Puede aplicar un tema antes del método setContentView en el método onCreate.
Luego, la aplicación de contactos puede aplicar un tema al azar a cada usuario.
Este método es:
setTheme(R.style.MyRandomTheme);
Pero este método tiene un problema, por ejemplo, puede cambiar el color de la barra de herramientas, el color del efecto de desplazamiento, el color de ondulación, etc., pero no puede cambiar el color de la barra de estado y el color de la barra de navegación (si quiere cambiarlo también).
Luego, para resolver este problema, puede usar el método antes y:
if (Build.VERSION.SDK_INT >= 21) {
getWindow().setNavigationBarColor(getResources().getColor(R.color.md_red_500));
getWindow().setStatusBarColor(getResources().getColor(R.color.md_red_700));
}
Estos dos métodos cambian la navegación y el color de la barra de estado. Recuerde, si configura su barra de navegación translúcida, no puede cambiar su color.
Este debería ser el código final:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(R.style.MyRandomTheme);
if (Build.VERSION.SDK_INT >= 21) {
getWindow().setNavigationBarColor(getResources().getColor(R.color.myrandomcolor1));
getWindow().setStatusBarColor(getResources().getColor(R.color.myrandomcolor2));
}
setContentView(R.layout.activity_main);
}
Puede usar un interruptor y generar un número aleatorio para usar temas aleatorios, o, como en la aplicación de contactos, cada contacto probablemente tenga asociado un número predefinido.
Una muestra de tema:
<style name="MyRandomTheme" parent="Theme.AppCompat.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/myrandomcolor1</item>
<item name="colorPrimaryDark">@color/myrandomcolor2</item>
<item name="android:navigationBarColor">@color/myrandomcolor1</item>
</style>
Lo siento por mi ingles.
Los temas son inmutables, no puedes.
Puede que esto no sea exactamente lo que quieres, pero esta respuesta funciona para mí.
Me gustaría ver el método también, donde estableces una vez para todas tus actividades. Pero hasta donde sé, debes establecer cada actividad antes de mostrar cualquier punto de vista.
Para referencia, verifique esto:
http://www.anddev.org/applying_a_theme_to_your_application-t817.html
Editar (copiado de ese foro):
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Call setTheme before creation of any(!) View.
setTheme(android.R.style.Theme_Dark);
// ...
setContentView(R.layout.main);
}
Puede usar Theme.applyStyle para modificar su tema en tiempo de ejecución al aplicarle otro estilo.
Digamos que tienes estas definiciones de estilo:
<style name="DefaultTheme" parent="Theme.AppCompat.Light">
<item name="colorPrimary">@color/md_lime_500</item>
<item name="colorPrimaryDark">@color/md_lime_700</item>
<item name="colorAccent">@color/md_amber_A400</item>
</style>
<style name="OverlayPrimaryColorRed">
<item name="colorPrimary">@color/md_red_500</item>
<item name="colorPrimaryDark">@color/md_red_700</item>
</style>
<style name="OverlayPrimaryColorGreen">
<item name="colorPrimary">@color/md_green_500</item>
<item name="colorPrimaryDark">@color/md_green_700</item>
</style>
<style name="OverlayPrimaryColorBlue">
<item name="colorPrimary">@color/md_blue_500</item>
<item name="colorPrimaryDark">@color/md_blue_700</item>
</style>
Ahora puedes parchar tu tema en el tiempo de ejecución así:
getTheme().applyStyle(R.style.OverlayPrimaryColorGreen, true);
¡El método applyStyle
debe applyStyle
antes de que el diseño se infle! A menos que cargue la vista manualmente, debe aplicar estilos al tema antes de llamar a setContentView
en su actividad.
Por supuesto, esto no se puede usar para especificar un color arbitrario, es decir, uno de cada 16 millones (256 3 ) colores. Pero si escribe un pequeño programa que genere las definiciones de estilo y el código de Java para usted, entonces algo como uno de 512 (8 3 ) debería ser posible.
Lo que hace que esto sea interesante es que puedes usar diferentes superposiciones de estilo para diferentes aspectos de tu tema. Simplemente agregue algunas definiciones de superposición para colorAccent
por ejemplo. Ahora puede combinar diferentes valores para color primario y color de acento casi arbitrariamente.
Usé el código de Dahnark, pero también necesito cambiar el fondo de ToolBar:
if (dark_ui) {
this.setTheme(R.style.Theme_Dark);
if (Build.VERSION.SDK_INT >= 21) {
getWindow().setNavigationBarColor(getResources().getColor(R.color.Theme_Dark_primary));
getWindow().setStatusBarColor(getResources().getColor(R.color.Theme_Dark_primary_dark));
}
} else {
this.setTheme(R.style.Theme_Light);
}
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.app_bar);
if(dark_ui) {
toolbar.setBackgroundColor(getResources().getColor(R.color.Theme_Dark_primary));
}
de una actividad que puedes hacer:
getWindow().setStatusBarColor(i color);
UTILICE UNA BARRA DE HERRAMIENTAS
Puede establecer dinámicamente un color de elemento de barra de herramientas personalizado creando una clase de barra de herramientas personalizada:
package view;
import android.app.Activity;
import android.content.Context;
import android.graphics.ColorFilter;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.support.v7.internal.view.menu.ActionMenuItemView;
import android.support.v7.widget.ActionMenuView;
import android.support.v7.widget.Toolbar;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AutoCompleteTextView;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
public class CustomToolbar extends Toolbar{
public CustomToolbar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// TODO Auto-generated constructor stub
}
public CustomToolbar(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public CustomToolbar(Context context) {
super(context);
// TODO Auto-generated constructor stub
ctxt = context;
}
int itemColor;
Context ctxt;
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
Log.d("LL", "onLayout");
super.onLayout(changed, l, t, r, b);
colorizeToolbar(this, itemColor, (Activity) ctxt);
}
public void setItemColor(int color){
itemColor = color;
colorizeToolbar(this, itemColor, (Activity) ctxt);
}
/**
* Use this method to colorize toolbar icons to the desired target color
* @param toolbarView toolbar view being colored
* @param toolbarIconsColor the target color of toolbar icons
* @param activity reference to activity needed to register observers
*/
public static void colorizeToolbar(Toolbar toolbarView, int toolbarIconsColor, Activity activity) {
final PorterDuffColorFilter colorFilter
= new PorterDuffColorFilter(toolbarIconsColor, PorterDuff.Mode.SRC_IN);
for(int i = 0; i < toolbarView.getChildCount(); i++) {
final View v = toolbarView.getChildAt(i);
doColorizing(v, colorFilter, toolbarIconsColor);
}
//Step 3: Changing the color of title and subtitle.
toolbarView.setTitleTextColor(toolbarIconsColor);
toolbarView.setSubtitleTextColor(toolbarIconsColor);
}
public static void doColorizing(View v, final ColorFilter colorFilter, int toolbarIconsColor){
if(v instanceof ImageButton) {
((ImageButton)v).getDrawable().setAlpha(255);
((ImageButton)v).getDrawable().setColorFilter(colorFilter);
}
if(v instanceof ImageView) {
((ImageView)v).getDrawable().setAlpha(255);
((ImageView)v).getDrawable().setColorFilter(colorFilter);
}
if(v instanceof AutoCompleteTextView) {
((AutoCompleteTextView)v).setTextColor(toolbarIconsColor);
}
if(v instanceof TextView) {
((TextView)v).setTextColor(toolbarIconsColor);
}
if(v instanceof EditText) {
((EditText)v).setTextColor(toolbarIconsColor);
}
if (v instanceof ViewGroup){
for (int lli =0; lli< ((ViewGroup)v).getChildCount(); lli ++){
doColorizing(((ViewGroup)v).getChildAt(lli), colorFilter, toolbarIconsColor);
}
}
if(v instanceof ActionMenuView) {
for(int j = 0; j < ((ActionMenuView)v).getChildCount(); j++) {
//Step 2: Changing the color of any ActionMenuViews - icons that
//are not back button, nor text, nor overflow menu icon.
final View innerView = ((ActionMenuView)v).getChildAt(j);
if(innerView instanceof ActionMenuItemView) {
int drawablesCount = ((ActionMenuItemView)innerView).getCompoundDrawables().length;
for(int k = 0; k < drawablesCount; k++) {
if(((ActionMenuItemView)innerView).getCompoundDrawables()[k] != null) {
final int finalK = k;
//Important to set the color filter in seperate thread,
//by adding it to the message queue
//Won''t work otherwise.
//Works fine for my case but needs more testing
((ActionMenuItemView) innerView).getCompoundDrawables()[finalK].setColorFilter(colorFilter);
// innerView.post(new Runnable() {
// @Override
// public void run() {
// ((ActionMenuItemView) innerView).getCompoundDrawables()[finalK].setColorFilter(colorFilter);
// }
// });
}
}
}
}
}
}
}
luego refiérase a él en su archivo de diseño. Ahora puedes establecer un color personalizado usando
toolbar.setItemColor(Color.Red);
Fuentes:
Encontré la información para hacer esto aquí: Cómo cambiar dinámicamente los iconos de la barra de herramientas de Android en color
y luego lo GitHub:AndroidDynamicToolbarItemColor , lo mejoré y lo GitHub:AndroidDynamicToolbarItemColor aquí: GitHub:AndroidDynamicToolbarItemColor