Подтвердить что ты не робот

Значок значка панели инструментов на Android

Я заметил, что использование тем AppCompat, иконки панели инструментов по умолчанию становятся тонированными атрибутом colorControlNormal в моем стиле.

<style name="MyTheme" parent="Theme.AppCompat">
    <item name="colorControlNormal">@color/yellow</item>
</style>

enter image description here

Как вы можете видеть выше, однако, это не происходит со всеми значками. Я предоставил знак "плюс", который я получил из официальных значков, и он не становится тонированным (я использовал "белую" версию png). Из того, что я понял из этого question, система отображает только значки только с альфа-каналом. Это правда?

Если это так: Есть ли место, где я могу найти знаковые значки, определенные в форме? Если нет - и если значки на панели инструментов должны быть альфа-только для тонирования - как Google ожидает, что мы будем использовать предоставленные значки на панели инструментов?

Где-то в SDK я нашел несколько значков, заканчивающихся на _alpha.png, и они действительно хорошо окрашиваются. Однако мне нужен полный набор значков материалов, и из официальных источников я мог найти только теги white, grey600 и black.

Применение ColorFilter во время выполнения было бы немного болезненным, и моя фактическая панель инструментов - с некоторыми значками, тонированными, а некоторые другие - выглядят неплохо.

4b9b3361

Ответ 1

Я вижу, что этот вопрос дает некоторые взгляды, поэтому я собираюсь опубликовать ответ для тех, кто не читает комментарии.

Мои гипотезы в вопросе были неправы, и это не вопрос альфа-каналов, по крайней мере, не извне. Дело в том, что, цитируя @alanv,

AppCompat только оттенки собственных значков. Пока вам нужно будет вручную оттенок любых значков, которые вы предоставляете отдельно от AppCompat.

Это может измениться в будущем, но также может и не быть. Из этого ответа вы также можете увидеть список значков (все они принадлежат к внутренней папке ресурсов appcompat, поэтому вы не можете их изменить), которые автоматически тонируются и с которым цвет.

Лично я использую colorControlNormal, который является черным или белым (или похожим оттенком), и импортирует значки с этим конкретным цветом. Цветные значки на цветном фоне выглядят немного плохо. Однако другое решение, которое мне показалось приятным, этот класс на github. Вы просто вызываете MenuColorizer.colorMenu() при создании меню.

Ответ 2

Другой вариант - использовать новую поддержку векторных чертежей в библиотеке поддержки.

См. 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>

Ответ 3

Вот решение, которое я использую. Вызовите tintAllIcons после onPrepareOptionsMenu или эквивалентного местоположения. Причиной 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);
                }
            }
        }
    }
}

Это не позаботится о переполнении, но для этого вы можете сделать это:

Разметка:

<android.support.v7.widget.Toolbar
    ...
    android:theme="@style/myToolbarTheme" />

Стили:

<style name="myToolbarTheme">
        <item name="colorControlNormal">#FF0000</item>
</style>

Это работает с appcompat v23.1.0.

Ответ 4

Я действительно смог сделать это на 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);
}

На этом этапе вы можете изменить его на любой желаемый цвет!

Ответ 5

Это окончательный и верный ответ. Сначала создайте стиль для панели инструментов следующим образом:

  <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" >
     <item name="iconTint">@color/primaryTextColor</item>
    <!--choice your favorite color-->
  </style>

Затем в своем основном приложении или теме деятельности добавьте эту строку

  <item name="actionBarPopupTheme">@style/AppTheme.PopupOverlay</item>

И, наконец, в вашем файле макета добавьте эту строку на панель инструментов

 android:theme="?attr/actionBarPopupTheme"

И тогда вы увидите значки панели инструментов, окрашенные в ваш любимый цвет

Ответ 6

Вы можете создать собственную панель инструментов, которая использует цвет оттенка при раздувании меню.

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

}

Просто убедитесь, что вы вызываете свой код Activity/Fragment:

toolbar.inflateMenu(R.menu.some_menu);
toolbar.setOnMenuItemClickListener(someListener);

Нет отражения, нет просмотра вида, и не столько кода, а?

И не используйте onCreateOptionsMenu/onOptionsItemSelected, если вы используете этот подход

Ответ 7

Для SDK 23 или выше:

<style name="AppThemeToolbar" parent="MyAppTheme">
        ....
        <item name="android:drawableTint">@color/secondaryLightColor</item>
    </style>
Моя панель инструментов

    <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>

Ответ 8

@NonNull
public static Drawable setTintDrawable(@NonNull Drawable drawable, @ColorInt int color) {
   drawable.clearColorFilter();
   drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
   drawable.invalidateSelf();
   Drawable wrapDrawable = DrawableCompat.wrap(drawable).mutate();
   DrawableCompat.setTint(wrapDrawable, color);
   return wrapDrawable;
 }

и вызовите следующим образом:

MenuItem location = menu.findItem(R.id.action_location);
DrawableUtils.setTintDrawable(location.getIcon(), Color.WHITE);

введите описание изображения здесь

Ответ 9

С androidX вы можете определить свою панель инструментов, как это

<androidx.appcompat.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:theme="@style/Toolbar" />

Затем расширьте тему AppCompat и установите свойство colorControlNormal так, как вам нравится:

<style name="Toolbar" parent="Theme.AppCompat.Light">
    <item name="colorControlNormal">@color/colorBaseWhite</item>
    <item name="android:background">@color/colorPrimary</item>
</style>

Ответ 10

Это можно сделать в Котлине с помощью:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    menu.getItem(0)?.icon?.setTint(Color.WHITE)
}
else {
    @Suppress("DEPRECATION")
    menu.getItem(0)?.icon?.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN)
}

Он должен работать на всех современных версиях Android и без сбоев завершится, если getItem или icon вернет ноль.

Ответ 11

В основном, когда вы устанавливаете меню, значок из трех точек приобретает цвет android: textColorSecondary из AppTheme, который по умолчанию имеет значение Black.

Поэтому, если вы не используете textColorSecondary в любом месте вашего проекта, вы можете просто добавить следующую строку

<item name="android:textColorSecondary">@color/White</item>

После добавления это может выглядеть так.

<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="android:textColorSecondary">@color/White</item>
</style>