joe1806772
joe1806772

Reputation: 616

Android Ripple drawable and state focused (DPAD navigation)

I'm trying to implement a ripple effect background for buttons in an Android TV and Amazon FireTV application (Navigation via DPAD). I'm using AppCompat, but since the default button styles all use the ripple i now use a custom drawable background without any ripple and just an ordinary selector.

The behavior I try to achieve

What actually happens

This color-mixture seems to be the default behavior of ripple drawables, which makes them practically unusable for TV applications.

Any chance I can escape this? What i want is basically a ripple THAT DOESN'T MODIFY THE BACKGORUND COLOR and only draws on top.

Upvotes: 4

Views: 1623

Answers (2)

Anatolij Samilkin
Anatolij Samilkin

Reputation: 1

I know this question is already old, but I found a solution which is working for me:

<?xml version="1.0" encoding="utf-8"?>
<ripple
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/ripple">
    <item android:id="@android:id/mask">
        <selector>
            <!-- for hard key, ripple should be visible -->
            <item android:state_pressed="true">
                <shape android:shape="rectangle">
                    <solid android:color="@android:color/black"/>
                    <corners android:radius="@dimen/cornerRadius"/>
                </shape>
            </item>
            <!-- on focused state, set the color to transparent, no ripple will be visible -->
            <item
                android:state_focused="true">
                <color android:color="@android:color/transparent"/>
            </item>
            <!-- default behavior, ripple should be visible-->
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="@android:color/black"/>
                    <corners android:radius="@dimen/cornerRadius"/>
                </shape>
            </item>
        </selector>
    </item>
    <!-- background color-->
    <item >
        <color android:color="@android:color/background"/>
    </item>
</ripple>

The problem on this behavior is the mask item. The documentation of RippleDrawable says:

If a mask layer is set, the ripple effect will be masked against that layer before it is drawn over the composite of the remaining child layers.

If no mask layer is set, the ripple effect is masked against the composite of the child layers.

As I understand, if you use DPAD/HardKeys, then the mask item will be focused. To exclude the mask item, I added a selector and overwrite the behavior of the focused state with an transparent color. So the mask will not be visible if the view is focused. As default behavior it is necessary to set a solid color for the mask, otherwise the ripple will not be visible. In my case I added a shape, because I want to have round corners for my ripple.

Additionally I added the pressed state for the selector, because I want to have also a ripple effect on HardKey enter.

At last point I added an additional item with my background color.

Upvotes: 0

tmm1
tmm1

Reputation: 2125

According to https://stackoverflow.com/a/29777616/332798, if you add a mask to your ripple that will make the default state transparent and won't affect the focused color anymore.

Upvotes: 0

Related Questions