1

I am trying to find a way so that app:tint values does not affect a specific subpath color of a drawable that is placed within a fab. The drawable svg is:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<group>
    <clip-path android:pathData="M0,0h20v20h-20z" />
    <path
        android:fillAlpha="0.12"
        android:fillColor="#000000"
        android:pathData="M10.0025,16.625L11.7326,10.5318L8.2723,10.5318L10.0025,16.625Z" />
    <path
        android:fillAlpha="0.87"
        android:fillColor="#ffffff"
        android:pathData="M3.909,3.9123C4.4355,3.3858 3.4576,2.4079 2.9311,2.9344C2.4045,3.461 3.3824,4.4389 3.909,3.9123Z" />
    <path
        android:fillAlpha="0.87"
        android:fillColor="#ffffff"
        android:pathData="M3.1568,16.0986C2.2541,17.0013 3.3824,17.5278 3.7586,17.1517C4.586,16.1738 3.6081,15.6472 3.1568,16.0986Z" />
    <path
        android:fillAlpha="0.87"
        android:fillColor="#ffffff"
        android:pathData="M1.4265,10.0055C1.4265,9.2533 0.0725,9.2533 0.0725,10.0055C0.0725,10.7577 1.4265,10.7577 1.4265,10.0055Z" />
    <path
        android:fillAlpha="0.87"
        android:fillColor="#ffffff"
        android:pathData="M16.3213,2.9342C15.4187,3.8369 16.547,4.3635 16.9984,3.9121C17.7506,3.0094 16.6975,2.5581 16.3213,2.9342Z" />
    <path
        android:fillAlpha="0.87"
        android:fillColor="#ffffff"
        android:pathData="M19.4052,10.532C20.007,10.532 20.3831,9.4036 19.1795,9.4036C18.5025,9.4788 18.2016,10.532 19.4052,10.532Z" />
    <path
        android:fillAlpha="0.87"
        android:fillColor="#ffffff"
        android:pathData="M16.0951,16.0986C15.5686,16.6252 16.5465,17.6031 17.073,17.0765C17.5996,16.55 16.6217,15.5721 16.0951,16.0986Z" />
    <path
        android:fillAlpha="0.87"
        android:fillColor="#ffffff"
        android:pathData="M10.0022,0.8281C9.7013,0.8281 9.5508,0.9786 9.4756,1.2043C9.1747,2.4078 6.8428,9.7046 6.918,10.0807L9.4756,18.6563C9.7013,19.1828 10.3783,19.258 10.5288,18.6563L13.0864,10.0807C13.2368,9.6294 10.8297,2.2574 10.604,1.129C10.4535,0.9786 10.2279,0.9034 10.0022,0.8281ZM10.0022,16.6252L8.272,10.532L11.7323,10.532L10.0022,16.6252ZM11.7323,9.4789L8.272,9.4789L10.0022,3.3858L11.7323,9.4789Z" />
    <path
        android:fillAlpha="1.0"
        android:fillColor="@color/red"
        android:pathData="M11.7326,9.4789L10.0025,3.3857L8.2723,9.4789L11.7326,9.4789Z" />
</group>

The drawable looks like this:

compass drawable

However, when setting app:backgroundTint or app:tint for the drawable itself, the colors are overridden and the outcome looks like:

wrong colors

or when i set app:tint for the drawable again, it overrides then red color that exist in the compass and shows as:

wrong again

Is there a way to leave the drawable partially unaffected by these values or by theme? I want to preserve the last part of the drawable specifically this:

<path
        android:fillAlpha="1.0"
        android:fillColor="@color/red"
        android:pathData="M11.7326,9.4789L10.0025,3.3857L8.2723,9.4789L11.7326,9.4789Z" />

(there is also a theme applied in the layout but I need it for other buttons.

RandomType
  • 47
  • 1
  • 8
  • check this answer https://stackoverflow.com/a/54086747/6478047 – Manohar Nov 18 '21 at 09:25
  • @Manohar No this is not what I want. I want the tint to actually affect parts of the drawable when for example the state of fab is set to `activated`. I have used `app:tint="@null"` for the drawable color but when the fab is set to `Activated` the drawable color is overriden as shown in the pictures. – RandomType Nov 18 '21 at 10:28
  • ok, I don't think It's possible . I will cast a reopen flag any way as its slightly different . – Manohar Nov 18 '21 at 10:35
  • You are applying tinr, but you dont want the tint to work? Why use tint in first place? – cutiko Nov 18 '21 at 10:38
  • @cutiko Actually tint is applied but the compass drawable has a red color somewhere that is overridden by the tint and so it is not shown as red. This is the main problem. Cant find a workaround.... – RandomType Nov 18 '21 at 10:52
  • From what I know , tint will replace full color , I don't think there is a way to apply partial tint – Manohar Nov 18 '21 at 11:23

1 Answers1

1

You can do this with a layer list and a decomposed compass drawable. Here is the decomposed vector drawable.

compass_arrow.xml
Notice that the red arrow path is removed and the tint is applied at the top.

<vector 
    android:width="20dp"
    android:height="20dp"
    android:tint="@color/black"
    android:viewportWidth="20"
    android:viewportHeight="20">
    <group>
        <clip-path android:pathData="M0,0h20v20h-20z" />
        <path
            android:fillAlpha="0.12"
            android:fillColor="#000000"
            android:pathData="M10.0025,16.625L11.7326,10.5318L8.2723,10.5318L10.0025,16.625Z" />
        <path
            android:fillAlpha="0.87"
            android:fillColor="#ffffff"
            android:pathData="M3.909,3.9123C4.4355,3.3858 3.4576,2.4079 2.9311,2.9344C2.4045,3.461 3.3824,4.4389 3.909,3.9123Z" />
        <path
            android:fillAlpha="0.87"
            android:fillColor="#ffffff"
            android:pathData="M3.1568,16.0986C2.2541,17.0013 3.3824,17.5278 3.7586,17.1517C4.586,16.1738 3.6081,15.6472 3.1568,16.0986Z" />
        <path
            android:fillAlpha="0.87"
            android:fillColor="#ffffff"
            android:pathData="M1.4265,10.0055C1.4265,9.2533 0.0725,9.2533 0.0725,10.0055C0.0725,10.7577 1.4265,10.7577 1.4265,10.0055Z" />
        <path
            android:fillAlpha="0.87"
            android:fillColor="#ffffff"
            android:pathData="M16.3213,2.9342C15.4187,3.8369 16.547,4.3635 16.9984,3.9121C17.7506,3.0094 16.6975,2.5581 16.3213,2.9342Z" />
        <path
            android:fillAlpha="0.87"
            android:fillColor="#ffffff"
            android:pathData="M19.4052,10.532C20.007,10.532 20.3831,9.4036 19.1795,9.4036C18.5025,9.4788 18.2016,10.532 19.4052,10.532Z" />
        <path
            android:fillAlpha="0.87"
            android:fillColor="#ffffff"
            android:pathData="M16.0951,16.0986C15.5686,16.6252 16.5465,17.6031 17.073,17.0765C17.5996,16.55 16.6217,15.5721 16.0951,16.0986Z" />
        <path
            android:fillAlpha="0.87"
            android:fillColor="#ffffff"
            android:pathData="M10.0022,0.8281C9.7013,0.8281 9.5508,0.9786 9.4756,1.2043C9.1747,2.4078 6.8428,9.7046 6.918,10.0807L9.4756,18.6563C9.7013,19.1828 10.3783,19.258 10.5288,18.6563L13.0864,10.0807C13.2368,9.6294 10.8297,2.2574 10.604,1.129C10.4535,0.9786 10.2279,0.9034 10.0022,0.8281ZM10.0022,16.6252L8.272,10.532L11.7323,10.532L10.0022,16.6252ZM11.7323,9.4789L8.272,9.4789L10.0022,3.3858L11.7323,9.4789Z" />
    </group>
</vector>

compass_red_arrow.xml
This is just the red arrow in its own file.

<vector 
    android:width="20dp"
    android:height="20dp"
    android:viewportWidth="20"
    android:viewportHeight="20">
    <group>
        <clip-path android:pathData="M0,0h20v20h-20z" />
        <path
            android:fillAlpha="1.0"
            android:fillColor="@android:color/holo_red_dark"
            android:pathData="M11.7326,9.4789L10.0025,3.3857L8.2723,9.4789L11.7326,9.4789Z" />
    </group>
</vector>

compass_layer_list.xml This puts it all together.

<layer-list>
    <item android:drawable="@drawable/compass_arrow" />
    <item android:drawable="@drawable/compass_red_arrow" />
</layer-list>

Here is what the final drawable looks like as the background of an ImageView with a rotation of 45 degrees:

enter image description here

You won't be able to tint from the layout XML, but you can tint the drawable without the red arrow using a theme attribute.

(I missed that this is a FAB. You may have to set app:tint="@null" on the FAB to override its inherent tinting.)

Update: Here is the technique in a FAB. The tint is set to orange in compass_arrow.xml. You can pull the color from the theme if you need to do that.

<com.google.android.material.floatingactionbutton.FloatingActionButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    app:fabSize="normal"
    android:layout_marginStart="150dp"
    app:tint="@null"
    android:src="@drawable/compass_layer_list"
    android:rotation="45" />

enter image description here

Second update: Actually, there is no need to split the drawable. We can set the colors we want in the drawable XML from the theme and set app:tint="@null" to stop inherent tinting. In the following code, the FAB tint is coming from ?attr/colorOnSecondary and is no longer hard-coded. I believe that this is the default tint that FABs use if no explicit tint is set.

Either of the preceding ways work, but this is simpler and maintains the tinting aspect of the FAB.

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="20dp"
    android:height="20dp"
    android:viewportWidth="20"
    android:viewportHeight="20">
    <group>
        <clip-path android:pathData="M0,0h20v20h-20z" />
        <path
            android:fillAlpha="0.87"
            android:fillColor="@android:color/holo_red_dark"
            android:pathData="M10.0025,16.625L11.7326,10.5318L8.2723,10.5318L10.0025,16.625Z" />
        <path
            android:fillAlpha="0.87"
            android:fillColor="?attr/colorOnSecondary"
            android:pathData="M3.909,3.9123C4.4355,3.3858 3.4576,2.4079 2.9311,2.9344C2.4045,3.461 3.3824,4.4389 3.909,3.9123Z" />
        <path
            android:fillAlpha="0.87"
            android:fillColor="?attr/colorOnSecondary"
            android:pathData="M3.1568,16.0986C2.2541,17.0013 3.3824,17.5278 3.7586,17.1517C4.586,16.1738 3.6081,15.6472 3.1568,16.0986Z" />
        <path
            android:fillAlpha="0.87"
            android:fillColor="?attr/colorOnSecondary"
            android:pathData="M1.4265,10.0055C1.4265,9.2533 0.0725,9.2533 0.0725,10.0055C0.0725,10.7577 1.4265,10.7577 1.4265,10.0055Z" />
        <path
            android:fillAlpha="0.87"
            android:fillColor="?attr/colorOnSecondary"
            android:pathData="M16.3213,2.9342C15.4187,3.8369 16.547,4.3635 16.9984,3.9121C17.7506,3.0094 16.6975,2.5581 16.3213,2.9342Z" />
        <path
            android:fillAlpha="0.87"
            android:fillColor="?attr/colorOnSecondary"
            android:pathData="M19.4052,10.532C20.007,10.532 20.3831,9.4036 19.1795,9.4036C18.5025,9.4788 18.2016,10.532 19.4052,10.532Z" />
        <path
            android:fillAlpha="0.87"
            android:fillColor="?attr/colorOnSecondary"
            android:pathData="M16.0951,16.0986C15.5686,16.6252 16.5465,17.6031 17.073,17.0765C17.5996,16.55 16.6217,15.5721 16.0951,16.0986Z" />
        <path
            android:fillAlpha="0.87"
            android:fillColor="?attr/colorOnSecondary"
            android:pathData="M10.0022,0.8281C9.7013,0.8281 9.5508,0.9786 9.4756,1.2043C9.1747,2.4078 6.8428,9.7046 6.918,10.0807L9.4756,18.6563C9.7013,19.1828 10.3783,19.258 10.5288,18.6563L13.0864,10.0807C13.2368,9.6294 10.8297,2.2574 10.604,1.129C10.4535,0.9786 10.2279,0.9034 10.0022,0.8281ZM10.0022,16.6252L8.272,10.532L11.7323,10.532L10.0022,16.6252ZM11.7323,9.4789L8.272,9.4789L10.0022,3.3858L11.7323,9.4789Z" />
    </group>
</vector>
Cheticamp
  • 61,413
  • 10
  • 78
  • 131
  • Well in case i have to use the `compass_layer_list.xml` in the fab button i would still have to use `app:tint` thus it would also override `compass_red_arrow` and `compass_arrow` right? – RandomType Nov 18 '21 at 16:15
  • Why do you need to use `app:tint`? Set it to `@null` and apply the tint in the drawable. The effect is the same. – Cheticamp Nov 18 '21 at 16:38
  • @RandomType Just posted a second method that is simpler. – Cheticamp Nov 18 '21 at 17:01
  • @RandomType So, what did you decide about a solution? – Cheticamp Nov 22 '21 at 20:05
  • I found a workaround to just add and remove tint on the fab. I think another solution would be to change the drawable on the fab dynamically but i havent search much about that method. – RandomType Nov 22 '21 at 20:42