Search code examples
androidmenumenuitemandroid-vectordrawable

MenuItem. ColorFilter. Rounded background


I use vector drawable for MenuItem.

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    this.menu = menu;
    menu.add(Menu.NONE, 1, Menu.NONE, "Pen")
            .setIcon(R.drawable.ic_pen)
            .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
    return true;
}

I have changeable variable "color". For Android version >= Lollipop I use setTin(color)

menuItem.getIcon().setTint(color);

For Android <= Lollipop I want to use setColorFilter(color, PorterDuff.Mode.SCREEN). It turns out such background (square)

menuItem.setColorFilter(color, PorterDuff.Mode.SCREEN);

enter image description here

How to make this background rounded?


Solution

  • You can create DrawableResource using layer-list. To make background rounded create new DrawableResource, let's name it ic_pen_rounded and put the next code into this file:

    <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
        <item>
            <shape android:shape="oval">
                <solid android:color="#8df"/>
                <size
                    android:width="100dp"
                    android:height="100dp" />
            </shape>
        </item>
        <item android:drawable="@drawable/ic_pen" />
    </layer-list>
    

    Then just use this Drawable when creating MenuItem:

    menu.add(Menu.NONE, 1, Menu.NONE, "Pen")
            .setIcon(R.drawable.ic_pen_round)
            .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
    

    And also you can get rid of lines where you setting background of the VectorDrawable:

    • menuItem.getIcon().setTint(color);
    • menuItem.setColorFilter(color, PorterDuff.Mode.SCREEN);

    You can set icon background in your ic_pen_rounded.xml, in the next line:

    <solid android:color="#8df"/>
    

    This is my result:

    enter image description here



    UPDATE - How to change icon background color at runtime

    1. Add id to your ShapeDrawable inside layer-list:

      <item
          android:id="@+id/background">
          <shape android:shape="oval">
              <solid android:color="#8df"/>
              <size
                  android:width="100dp"
                  android:height="100dp" />
          </shape>
      </item>
      
    2. Get menuItem icon:

      LayerDrawable layerDrawable = (LayerDrawable) menuItem.getIcon();
      
    3. Find background item by id and set color:

      GradientDrawable icon = (GradientDrawable) layerDrawable.findDrawableByLayerId(R.id.background);
      icon.setColor(Color.RED);