如何在Android棒棒糖中以编程方式更改主要和重音颜色?

首先, 这个问题提出了一个非常类似的问题。 但是,我的问题有一个微妙的差别。

我想知道的是,是否可以通过编程方式将主题的colorPrimary属性更改为任意颜色?

举例来说,我们有:

 <style name="AppTheme" parent="android:Theme.Material.Light"> <item name="android:colorPrimary">#ff0000</item> <item name="android:colorAccent">#ff0000</item> </style> 

在运行时,用户决定将#ccffff作为主要颜色。 当然,我无法为所有可能的颜色创build主题。

我不介意,只要使用公共SDK工作,就必须依靠Android的私有内部工具来做黑客行为。

我的目标是最终让ActionBar CheckBox 所有小部件使用这个主要颜色。

主题是不可改变的,你不能。

我阅读关于联系人应用程序的评论以及如何使用每个联系人的主题。

联系人应用程序可能有一些预定义的主题(对于每个材料的主要颜色来自http://www.google.com/design/spec/style/color.html )。

您可以在onCreate方法内的setContentView方法之前应用主题。

然后联系人应用程序可以为每个用户随机应用一个主题。

这种方法是:

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

您可以使用开关并生成随机数字以使用随机主题,或者像在联系人应用中一样,每个联系人可能都有一个预定义的关联号码。

主题示例:

 <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> 

对不起我的英语不好。

您可以使用Theme.applyStyle在运行时通过应用另一个样式来修改主题。

假设您有这些样式定义:

 <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> 

现在,您可以在运行时修补您的主题,如下所示:

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

当然,这不能用于指定任意颜色,即1600万(256 3 )种颜色中的一种。 但是,如果你编写一个小程序来为你生成样式定义和Java代码,那么512(8 3 )中的一个应该是可能的。

让这个有趣的是,你可以为你的主题的不同方面使用不同的风格叠加。 例如,为colorAccent添加一些重叠定义。 现在,您可以几乎任意组合不同的原色和重点颜色值。

GreenMatter库可以帮助您实现您正在寻找的function:

https://github.com/negusoft/GreenMatter

我使用Dahnark的代码,但我也需要更改工具栏背景:

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

使用工具栏

您可以通过创build自定义工具栏类来dynamic设置自定义工具栏项目的颜色:

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

资料来源:

我发现信息在这里做到这一点: 如何dynamic地改变Android的工具栏图标的颜色

然后我编辑它,改进它,并在这里发布: GitHub:AndroidDynamicToolbarItemColor

这是你可以做的:

写一个文件在可绘制文件夹中,让它命名为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> 

然后设置您的布局(或以往的情况) android:background="@drawable/background"

在设置你的主题这个颜色将代表相同。

从一项活动你可以做到:

 getWindow().setStatusBarColor(i color);