Как _really_ программно изменить основной и акцентный цвет в Android Lollipop?

Прежде всего, этот вопрос задает очень похожий вопрос. Однако мой вопрос имеет тонкую разницу.

Я хотел бы знать, можно ли программно изменить атрибут colorPrimary темы на произвольный цвет?

Так, например, мы имеем:

  #ff0000 #ff0000  

Во время выполнения пользователь решает, что хочет использовать #ccffff в качестве основного цвета. Конечно, я не могу создавать темы для всех возможных цветов.

Я не возражаю, если мне нужно делать хакерские вещи, например, полагаться на частные внутренние компоненты Android, если они работают с использованием общедоступного SDK.

Моя цель состоит в том, чтобы в конечном итоге ActionBar и все виджеты, такие как CheckBox использовали этот основной цвет.

Темы неизменны, вы не можете.

Я прочитал комментарии о приложении для контактов и о том, как он использует тему для каждого контакта.

Возможно, приложение для контактов имеет некоторые предопределенные темы (для каждого основного основного материала здесь: http://www.google.com/design/spec/style/color.html ).

Вы можете применить тему до метода setContentView внутри метода onCreate.

Затем приложение-приложение может произвольно применять тему к каждому пользователю.

Этот метод:

 setTheme(R.style.MyRandomTheme); 

Но у этого метода есть проблема, например, он может изменить цвет панели инструментов, цвет эффекта прокрутки, цвет пульсации и т. Д., Но он не может изменить цвет строки состояния и цвет панели навигации (если вы тоже хотите его изменить).

Затем для решения этой проблемы вы можете использовать метод до и:

 if (Build.VERSION.SDK_INT >= 21) { getWindow().setNavigationBarColor(getResources().getColor(R.color.md_red_500)); getWindow().setStatusBarColor(getResources().getColor(R.color.md_red_700)); } 

Этот два метода изменяет цвет навигации и строки состояния. Помните, что если вы установите прозрачную навигационную панель, вы не сможете изменить ее цвет.

Это должен быть конечный код:

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

Вы можете использовать переключатель и генерировать случайное число для использования случайных тем, или, как в приложении для контактов, у каждого контакта, вероятно, есть предопределенный номер.

Образец темы:

  

Извините за мой английский.

Вы можете использовать Theme.applyStyle для изменения темы во время выполнения, применяя к ней другой стиль.

Допустим, у вас есть эти определения стиля:

     

Теперь вы можете исправлять свою тему во время выполнения следующим образом:

 getTheme().applyStyle(R.style.OverlayPrimaryColorGreen, true); 

Метод applyStyle должен быть вызван до того, как макет будет завышен! Поэтому, если вы не загрузите представление вручную, вы должны применить стили к теме перед вызовом setContentView в своей деятельности.

Конечно, это нельзя использовать для указания произвольного цвета, то есть одного из 16 миллионов (256 3 ) цветов. Но если вы пишете небольшую программу, которая генерирует определения стиля и код Java для вас, то должно быть возможно что-то вроде одного из 512 (8 3 ).

Интересно то, что вы можете использовать разные наложения стиля для разных аспектов вашей темы. Просто добавьте несколько описаний наложения для colorAccent например. Теперь вы можете комбинировать разные значения для основного цвета и цвета акцента почти произвольно.

Я создал некоторое решение для создания цветных тем, возможно, это может быть полезно для кого-то. API 9+

1. сначала создайте « res / values-v9 / » и поместите туда этот файл: styles.xml и регулярная папка «res / values» будут использоваться с вашими стилями.

2. поместите этот код в свои res / values ​​/ styles.xml:

      

3. в AndroidManifest:

  

4. Создайте новый class с именем “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. и перед вызовом setContentView (R.layout.activity_main) просто добавьте:

 new ThemeColors(this); 

для изменения цвета заменить Random на 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); } }); 

введите описание изображения здесь

Библиотека GreenMatter может помочь вам в достижении нужной функциональности:

https://github.com/negusoft/GreenMatter

Я использовал код Данарка, но мне также нужно изменить фон 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)); } 

Это может быть не совсем то, что вы хотите, но этот ответ работает на меня.

Я также хотел бы увидеть этот метод, где вы задали один раз для всех своих действий. Но насколько я знаю, вы должны установить в каждом мероприятии, прежде чем показывать какие-либо мнения.

Для справки проверьте это:

http://www.anddev.org/applying_a_theme_to_your_application-t817.html

Изменить (скопировано с этого форума):

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

ИСПОЛЬЗУЙТЕ ИНСТРУМЕНТ

Динамически настраивать динамический элемент панели инструментов можно, создав собственный class панели инструментов:

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

затем обратитесь к нему в файл макета. Теперь вы можете установить собственный цвет, используя

 toolbar.setItemColor(Color.Red); 

Источники:

Я нашел информацию, чтобы сделать это здесь: Как динамически изменить цвет значков панели инструментов Android

а затем я отредактировал его, улучшил его и разместил здесь: GitHub: AndroidDynamicToolbarItemColor

Это то, что вы МОЖЕТЕ сделать:

напишите файл в папке с возможностью переноса, давайте назовите его background.xml

     

затем установите свой макет (или, что так всегда бывает). android:background="@drawable/background"

при настройке вашей темы этот цвет будет представлять собой то же самое.

от деятельности, которую вы можете сделать:

 getWindow().setStatusBarColor(i color); 
  • Уведомление о Heads-Up - Android Lollipop
  • Значок панели уведомлений становится белым в Android 5 Lollipop
  • Альтернатива getRunningTasks в Android L
  • Android 5.0 android: elevation Works for View, но не кнопка?
  • Как стилизовать DrawerArrowToggle из библиотеки Android appcompat v7 21
  • полностью прозрачная строка состояния и панель навигации на леденец
  • Давайте будем гением компьютера.