如何在没有样式工具栏的情况下动态更改所有工具栏的图标颜色
How to change all ToolBar's icons color dynamically without styling toolbar
我一直在寻找一种方法来动态更改工具栏中 所有 元素的颜色,就像 ActionBar 一样。
规格:
- 在 styles.xml
上使用 parent="Theme.AppCompat.Light.NoActionBar"
- Appcompat v7 22
- 在我的
AppCompatActivity
中设置 setSupportActionBar()
- 我从 POST 请求中得到了颜色(通常是 #FF------ 格式)
我已阅读以下内容post:
- Can't change navigation drawer icon color in android
- ActionBarDrawerToggle v7 arrow color
- Android burger/arrow icon dynamic change color(这个在某种程度上起作用了,但我不喜欢使用没有动画的自己的图像)。
以及与此主题相关的其他链接...none 其中对我有用。
我现在正在做的是在工具栏上搜索 ImageButton (),然后将 setColorFilter()
应用于所有这些按钮,如下面的代码:
for (int i = 0; i < toolbar.getChildCount(); i++){
if (toolbar.getChildAt(i) instanceof ImageButton) {
ImageButton ib = (ImageButton) toolbar.getChildAt(i);
ib.setColorFilter(Color.parseColor("#A74231"), PorterDuff.Mode.SRC_ATOP);
}
}
我正在更改背景和文本颜色:toolbar.setBackgroundColor
和 toolbar.setTitleTextColor
。
对于菜单图标(包括溢出菜单图标):
MenuItem item2 = mMenu.findItem(R.id.actionbar_group_moreoverflow);
item2.getIcon().setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
问题:是否有更好的方法(动态更改工具栏的元素颜色)?
要获取所有工具栏视图,遍历它的所有子视图并分别给它们着色。它的循环代码如下所示:
public static void colorizeToolbar(Toolbar toolbarView, int toolbarIconsColor, Activity activity) {
final PorterDuffColorFilter colorFilter
= new PorterDuffColorFilter(toolbarIconsColor, PorterDuff.Mode.MULTIPLY);
for(int i = 0; i < toolbarView.getChildCount(); i++) {
final View v = toolbarView.getChildAt(i);
//Step 1 : Changing the color of back button (or open drawer button).
if(v instanceof ImageButton) {
//Action Bar back button
((ImageButton)v).getDrawable().setColorFilter(colorFilter);
}
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.
innerView.post(new Runnable() {
@Override
public void run() {
((ActionMenuItemView) innerView).getCompoundDrawables()[finalK].setColorFilter(colorFilter);
}
});
}
}
}
}
}
//Step 3: Changing the color of title and subtitle.
toolbarView.setTitleTextColor(toolbarIconsColor);
toolbarView.setSubtitleTextColor(toolbarIconsColor);
//Step 4: Changing the color of the Overflow Menu icon.
setOverflowButtonColor(activity, colorFilter);
}
}
其次,实现负责查找和着色溢出图标的方法:
private static void setOverflowButtonColor(final Activity activity, final PorterDuffColorFilter colorFilter) {
final String overflowDescription = activity.getString(R.string.abc_action_menu_overflow_description);
final ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
final ViewTreeObserver viewTreeObserver = decorView.getViewTreeObserver();
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
final ArrayList<View> outViews = new ArrayList<View>();
decorView.findViewsWithText(outViews, overflowDescription,
View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);
if (outViews.isEmpty()) {
return;
}
TintImageView overflow=(TintImageView) outViews.get(0);
overflow.setColorFilter(colorFilter);
removeOnGlobalLayoutListener(decorView,this);
}
});
}
工具栏背景颜色
mToolbarView.setBackgroundColor(color);
ToolbarColorizeHelper.colorizeToolbar(mToolbarView, mToolbarIconsColor, getActivity());
看看这个link,它可能会对你有所帮助https://snow.dog/blog/how-to-dynamicaly-change-android-toolbar-icons-color/
我在这里遇到了同样的问题。我为 ToolBar 的元素做了什么:
- 背景颜色:
toolbar.setBackgroundColor(Color.parseColor("#xxxxxxxx"));
- 文字颜色:
toolbar.setTitleTextColor(Color.parseColor("#xxxxxxxx"));
对于 hamburger/drawer 按钮:
int color = Color.parseColor("#xxxxxxxx");
final PorterDuffColorFilter colorFilter = new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP);
for (int i = 0; i < toolbar.getChildCount(); i++){
final View v = toolbar.getChildAt(i);
if(v instanceof ImageButton) {
((ImageButton)v).setColorFilter(colorFilter);
}
}
对于 ActionMenuItemView(工具栏的按钮包括溢出按钮):
private void colorizeToolBarItem(AppCompatActivity activity, final PorterDuffColorFilter colorFilter, final String description) {
final ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
final ViewTreeObserver viewTreeObserver = decorView.getViewTreeObserver();
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
final ArrayList<View> outViews = new ArrayList<>();
decorView.findViewsWithText(outViews, description,
View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);
if (outViews.isEmpty())
return;
ActionMenuItemView overflow = (ActionMenuItemView)outViews.get(0);
overflow.getCompoundDrawables()[0].setColorFilter(colorFilter);
removeOnGlobalLayoutListener(decorView,this);
}
});
}
对于溢出菜单的项目文本:
我一直在寻找一种方法来动态更改工具栏中 所有 元素的颜色,就像 ActionBar 一样。
规格:
- 在 styles.xml 上使用
- Appcompat v7 22
- 在我的
AppCompatActivity
中设置 - 我从 POST 请求中得到了颜色(通常是 #FF------ 格式)
parent="Theme.AppCompat.Light.NoActionBar"
setSupportActionBar()
我已阅读以下内容post:
- Can't change navigation drawer icon color in android
- ActionBarDrawerToggle v7 arrow color
- Android burger/arrow icon dynamic change color(这个在某种程度上起作用了,但我不喜欢使用没有动画的自己的图像)。
以及与此主题相关的其他链接...none 其中对我有用。
我现在正在做的是在工具栏上搜索 ImageButton (setColorFilter()
应用于所有这些按钮,如下面的代码:
for (int i = 0; i < toolbar.getChildCount(); i++){
if (toolbar.getChildAt(i) instanceof ImageButton) {
ImageButton ib = (ImageButton) toolbar.getChildAt(i);
ib.setColorFilter(Color.parseColor("#A74231"), PorterDuff.Mode.SRC_ATOP);
}
}
我正在更改背景和文本颜色:toolbar.setBackgroundColor
和 toolbar.setTitleTextColor
。
对于菜单图标(包括溢出菜单图标):
MenuItem item2 = mMenu.findItem(R.id.actionbar_group_moreoverflow);
item2.getIcon().setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
问题:是否有更好的方法(动态更改工具栏的元素颜色)?
要获取所有工具栏视图,遍历它的所有子视图并分别给它们着色。它的循环代码如下所示:
public static void colorizeToolbar(Toolbar toolbarView, int toolbarIconsColor, Activity activity) {
final PorterDuffColorFilter colorFilter
= new PorterDuffColorFilter(toolbarIconsColor, PorterDuff.Mode.MULTIPLY);
for(int i = 0; i < toolbarView.getChildCount(); i++) {
final View v = toolbarView.getChildAt(i);
//Step 1 : Changing the color of back button (or open drawer button).
if(v instanceof ImageButton) {
//Action Bar back button
((ImageButton)v).getDrawable().setColorFilter(colorFilter);
}
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.
innerView.post(new Runnable() {
@Override
public void run() {
((ActionMenuItemView) innerView).getCompoundDrawables()[finalK].setColorFilter(colorFilter);
}
});
}
}
}
}
}
//Step 3: Changing the color of title and subtitle.
toolbarView.setTitleTextColor(toolbarIconsColor);
toolbarView.setSubtitleTextColor(toolbarIconsColor);
//Step 4: Changing the color of the Overflow Menu icon.
setOverflowButtonColor(activity, colorFilter);
}
}
其次,实现负责查找和着色溢出图标的方法:
private static void setOverflowButtonColor(final Activity activity, final PorterDuffColorFilter colorFilter) {
final String overflowDescription = activity.getString(R.string.abc_action_menu_overflow_description);
final ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
final ViewTreeObserver viewTreeObserver = decorView.getViewTreeObserver();
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
final ArrayList<View> outViews = new ArrayList<View>();
decorView.findViewsWithText(outViews, overflowDescription,
View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);
if (outViews.isEmpty()) {
return;
}
TintImageView overflow=(TintImageView) outViews.get(0);
overflow.setColorFilter(colorFilter);
removeOnGlobalLayoutListener(decorView,this);
}
});
}
工具栏背景颜色
mToolbarView.setBackgroundColor(color);
ToolbarColorizeHelper.colorizeToolbar(mToolbarView, mToolbarIconsColor, getActivity());
看看这个link,它可能会对你有所帮助https://snow.dog/blog/how-to-dynamicaly-change-android-toolbar-icons-color/
我在这里遇到了同样的问题。我为 ToolBar 的元素做了什么:
- 背景颜色:
toolbar.setBackgroundColor(Color.parseColor("#xxxxxxxx"));
- 文字颜色:
toolbar.setTitleTextColor(Color.parseColor("#xxxxxxxx"));
对于 hamburger/drawer 按钮:
int color = Color.parseColor("#xxxxxxxx"); final PorterDuffColorFilter colorFilter = new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP); for (int i = 0; i < toolbar.getChildCount(); i++){ final View v = toolbar.getChildAt(i); if(v instanceof ImageButton) { ((ImageButton)v).setColorFilter(colorFilter); } }
对于 ActionMenuItemView(工具栏的按钮包括溢出按钮):
private void colorizeToolBarItem(AppCompatActivity activity, final PorterDuffColorFilter colorFilter, final String description) { final ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView(); final ViewTreeObserver viewTreeObserver = decorView.getViewTreeObserver(); viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { final ArrayList<View> outViews = new ArrayList<>(); decorView.findViewsWithText(outViews, description, View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION); if (outViews.isEmpty()) return; ActionMenuItemView overflow = (ActionMenuItemView)outViews.get(0); overflow.getCompoundDrawables()[0].setColorFilter(colorFilter); removeOnGlobalLayoutListener(decorView,this); } }); }
对于溢出菜单的项目文本: