Android上的工具栏图标着色

nat*_*rio 34 android android-icons android-5.0-lollipop android-toolbar

我注意到使用AppCompat主题时,默认工具栏图标会被colorControlNormal我的样式中的属性着色.

<style name="MyTheme" parent="Theme.AppCompat">
    <item name="colorControlNormal">@color/yellow</item>
</style>
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

但是,正如您在上面所看到的,所有图标都不会发生这种情况.我提供了"加号"标志,这是我从官方图标中得到的,并没有得到着色(我使用了png的"白色"版本).根据我从这个问题中理解的,系统只显示带有alpha通道的图标.这是真的?

如果是这样的话:有没有可以找到alpha定义的官方素材图标的地方?如果不是 - 并且如果工具栏图标需要仅为alpha设色 - Google如何期望我们在工具栏中使用提供的图标?

在SDK的某个地方,我发现了一些以图标结尾的图标_alpha.png,它们实际上得到了很好的印记.不过,我需要的全套材料图标,并从官方渠道我只能找到white,grey600black人.

ColorFilter在运行时应用会有点痛苦,而我的实际工具栏 - 有些图标有色,有些没有 - 看起来很糟糕.

Joe*_*eer 25

另一种选择是在支持库中使用对矢量drawable的新支持.

请参阅res/xml/ic_search.xml博客文章AppCompat - 向量的年龄

注意引用 ?attr/colorControlNormal

<vector xmlns:android="..."
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0"
    android:tint="?attr/colorControlNormal">
    <path
        android:pathData="..."
        android:fillColor="@android:color/white"/>
</vector>
Run Code Online (Sandbox Code Playgroud)


Lea*_* ES 22

这是我使用的解决方案.在onPrepareOptionsMenu或等效位置后调用tintAllIcons.mutate()的原因是你碰巧在多个位置使用图标; 没有变异,他们都将采取相同的色彩.

public class MenuTintUtils {
    public static void tintAllIcons(Menu menu, final int color) {
        for (int i = 0; i < menu.size(); ++i) {
            final MenuItem item = menu.getItem(i);
            tintMenuItemIcon(color, item);
            tintShareIconIfPresent(color, item);
        }
    }

    private static void tintMenuItemIcon(int color, MenuItem item) {
        final Drawable drawable = item.getIcon();
        if (drawable != null) {
            final Drawable wrapped = DrawableCompat.wrap(drawable);
            drawable.mutate();
            DrawableCompat.setTint(wrapped, color);
            item.setIcon(drawable);
        }
    }

    private static void tintShareIconIfPresent(int color, MenuItem item) {
        if (item.getActionView() != null) {
            final View actionView = item.getActionView();
            final View expandActivitiesButton = actionView.findViewById(R.id.expand_activities_button);
            if (expandActivitiesButton != null) {
                final ImageView image = (ImageView) expandActivitiesButton.findViewById(R.id.image);
                if (image != null) {
                    final Drawable drawable = image.getDrawable();
                    final Drawable wrapped = DrawableCompat.wrap(drawable);
                    drawable.mutate();
                    DrawableCompat.setTint(wrapped, color);
                    image.setImageDrawable(drawable);
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这不会处理溢出,但为此,您可以这样做:

布局:

<android.support.v7.widget.Toolbar
    ...
    android:theme="@style/myToolbarTheme" />
Run Code Online (Sandbox Code Playgroud)

样式:

<style name="myToolbarTheme">
        <item name="colorControlNormal">#FF0000</item>
</style>
Run Code Online (Sandbox Code Playgroud)

这适用于appcompat v23.1.0.


Yus*_*ama 16

我实际上能够在API 10(Gingerbread)上做到这一点并且它工作得非常好.

编辑:它也适用于API 22 ......

这是最终的结果.

在此输入图像描述

注意:图标是可绘制文件夹中的可绘制资源.

现在这是它的完成方式:

@Override
public void onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);

    MenuItem item = menu.findItem(R.id.action_refresh);
    Drawable icon = getResources().getDrawable(R.drawable.ic_refresh_white_24dp);
    icon.setColorFilter(getResources().getColor(R.color.colorAccent), PorterDuff.Mode.SRC_IN);

    item.setIcon(icon);
}
Run Code Online (Sandbox Code Playgroud)

此时,您可以将其更改为您想要的任何颜色!


Ali*_*adi 8

这是最终的正确答案。首先为工具栏创建样式,如下所示:

  <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" >
     <item name="iconTint">@color/primaryTextColor</item>
    <!--choice your favorite color-->
  </style>
Run Code Online (Sandbox Code Playgroud)

然后在您的主应用程序或活动主题中添加此行

  <item name="actionBarPopupTheme">@style/AppTheme.PopupOverlay</item>
Run Code Online (Sandbox Code Playgroud)

最后在您的布局文件中,将此行添加到工具栏

 android:theme="?attr/actionBarPopupTheme"
Run Code Online (Sandbox Code Playgroud)

然后,您将看到工具栏图标以您喜欢的颜色着色


nat*_*rio 6

我看到这个问题正在得到一些观点,所以我将为那些没有阅读评论的人发布答案.

我对这个问题的推测都是错误的,这不是alpha通道的问题,至少不是外部的.事实很简单,引用@alanv,

AppCompat只对自己的图标进行着色.目前,您需要手动为与AppCompat分开提供的任何图标着色.

这可能在未来发生变化,但也可能不会发生变化.从这个答案中你还可以看到自动着色和使用哪种颜色的图标列表(它们都属于appcompat的内部资源文件夹,因此你无法更改它们).

我个人使用的colorControlNormal是黑色或白色(或类似的色调),并导入具有该特定颜色的图标.在色的背景的色的象看起来有点坏.然而,我发现另一个令人愉快的解决方案是github上的这个类.您只需MenuColorizer.colorMenu()在创建菜单时调用.


Dre*_*rew 5

您可以创建一个自定义工具栏,在膨胀菜单时使用您的色调。

public class MyToolbar extends Toolbar {
    ... some constructors, extracting mAccentColor from AttrSet, etc

    @Override
    public void inflateMenu(@MenuRes int resId) {
        super.inflateMenu(resId);
        Menu menu = getMenu();
        for (int i = 0; i < menu.size(); i++) {
            MenuItem item = menu.getItem(i);
            Drawable icon = item.getIcon();
            if (icon != null) {
                item.setIcon(applyTint(icon));
            }
        }
    }
    void applyTint(Drawable icon){
        icon.setColorFilter(
           new PorterDuffColorFilter(mAccentColor, PorterDuff.Mode.SRC_IN)
        );
    }

}
Run Code Online (Sandbox Code Playgroud)

只要确保你调用了你的 Activity/Fragment 代码:

toolbar.inflateMenu(R.menu.some_menu);
toolbar.setOnMenuItemClickListener(someListener);
Run Code Online (Sandbox Code Playgroud)

没有反射,没有视图查找,也没有那么多代码,是吧?

并且不要使用onCreateOptionsMenu/onOptionsItemSelected,如果您使用这种方法


mlu*_*nap 5

对于 sdk 23 或更高版本:

<style name="AppThemeToolbar" parent="MyAppTheme">
        ....
        <item name="android:drawableTint">@color/secondaryLightColor</item>
    </style>
Run Code Online (Sandbox Code Playgroud) 我的工具栏

    <com.google.android.material.appbar.AppBarLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content">
      <androidx.appcompat.widget.Toolbar
          android:theme="@style/AppThemeToolbar"
          android:layout_width="match_parent"
          android:layout_height="attr/actionBarSize">
      </androidx.appcompat.widget.Toolbar>
    </com.google.android.material.appbar.AppBarLayout>

Run Code Online (Sandbox Code Playgroud)