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

时间:2015-09-14 16:55:53

标签: android android-appcompat android-toolbar android-imagebutton

我一直在寻找一种方法来改变动态工具栏中所有元素的颜色。

规格:

  • 在styles.xml上使用parent="Theme.AppCompat.Light.NoActionBar"
  • Appcompat v7 22
  • setSupportActionBar()
  • 中设置AppCompatActivity
  • 我从POST请求中获得了颜色(通常是#FF ------ format)

我读过以下帖子:

  1. How do I change the color of the ActionBar hamburger icon?
  2. How to change color of hamburger icon in material design navigation drawer
  3. Can't change navigation drawer icon color in android
  4. ActionBarDrawerToggle v7 arrow color
  5. Android Toolbar color change
  6. Android burger/arrow icon dynamic change color(这个有点工作,但我不喜欢用动画制作自己的图像)。
    还有其他与此主题相关的链接......这些链接都不适合我。

  7. 我现在正在做的是在工具栏上搜索ImageButton(Get reference to drawer toggle in support actionbar),并将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);
    


    问题:是否有更好的方法(动态更改工具栏的元素颜色)?

2 个答案:

答案 0 :(得分:4)

我在这里面临同样的问题。我为ToolBar的元素做了什么:

  1. 背景颜色:toolbar.setBackgroundColor(Color.parseColor("#xxxxxxxx"));
  2. 对于文字颜色:toolbar.setTitleTextColor(Color.parseColor("#xxxxxxxx"));
  3. 汉堡/抽屉按钮:

    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. 对于溢出菜单的项目文字:take a look at this link

答案 1 :(得分:0)

要获取所有工具栏视图,请遍历其所有子视图并单独着色。它的循环代码如下所示:

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

看一下这个链接,它可以帮助你https://snow.dog/blog/how-to-dynamicaly-change-android-toolbar-icons-color/