【问题标题】:How to change all ToolBar's icons color dynamically without styling toolbar如何在没有样式工具栏的情况下动态更改所有工具栏的图标颜色
【发布时间】:2015-09-14 16:55:53
【问题描述】:

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

规格:

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

我已阅读以下帖子:

  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(这个在某种程度上可以工作,但我不喜欢使用自己的图像而没有动画)。
    以及与此主题相关的其他链接...它们都不适合我。

我现在正在做的是在工具栏上搜索 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);


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

【问题讨论】:

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


    【解决方案1】:

    我在这里遇到了同样的问题。我为 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

    【讨论】:

    • 根据@Shishram 的回答,我正在做与您类似的事情。但仍然缺少如何为溢出菜单的背景和图标着色。
    【解决方案2】:

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

    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/

    【讨论】:

    • Ty 的答案,但你能详细解释一下它将如何帮助我解决这个问题吗? (动态改变它)。不知道我是否不够清楚,或者您的答案中有一些我没有看到的东西,我的意思是,我说的是动态且没有风格。
    • 抱歉,我已经删除了所有不需要的代码,请检查答案中的链接它可能会对您有所帮助!
    • 当然,我会添加必要的部分。
    • 使用它,我遇到了一些关于 PorterDuff.Mode 的问题,我猜我找到了溢出按钮的简便方法,让我完成我的代码,我会完成你的答案并将其标记为正确(如果一切正常)。
    • 好的,在处理完代码后,我给你一份简历:我将 PorterDebuff.Mode.MULTIPLY 更改为 SRC_ATOP look at this post and the link in it。我不得不将这一行 ((ImageButton)v).getDrawable().setColorFilter(colorFilter); 更改为 ((ImageButton)v).setColorFilter(colorFilter);,因为第一个行不工作。第 2 步和第 4 步都不起作用,我正在寻找我该怎么做...
    猜你喜欢
    • 1970-01-01
    • 2021-07-19
    • 2019-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-09
    • 2019-08-19
    • 1970-01-01
    相关资源
    最近更新 更多