如何在没有样式工具栏的情况下动态更改所有工具栏的图标颜色

How to change all ToolBar's icons color dynamically without styling toolbar

我一直在寻找一种方法来动态更改工具栏中 所有 元素的颜色,就像 ActionBar 一样。

规格:

我已阅读以下内容post:

  1. Can't change navigation drawer icon color in android
  2. ActionBarDrawerToggle v7 arrow color
  3. 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.setBackgroundColortoolbar.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 的元素做了什么:

  1. 背景颜色:toolbar.setBackgroundColor(Color.parseColor("#xxxxxxxx"));
  2. 文字颜色:toolbar.setTitleTextColor(Color.parseColor("#xxxxxxxx"));
  3. 对于 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);
        }
    }
    
  4. 对于 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);
            }
        });
    }
    
  5. 对于溢出菜单的项目文本: