Android Ripple 可绘制和以状态为中心(DPAD 导航)

Posted

技术标签:

【中文标题】Android Ripple 可绘制和以状态为中心(DPAD 导航)【英文标题】:Android Ripple drawable and state focused (DPAD navigation) 【发布时间】:2017-06-26 19:45:50 【问题描述】:

我正在尝试为 android TV 和 Amazon FireTV 应用程序中的按钮实现涟漪效果背景(通过 DPAD 导航)。我正在使用 AppCompat,但由于默认按钮样式都使用波纹,我现在使用自定义可绘制背景,没有任何波纹,只是一个普通的选择器。

我试图实现的行为

默认(无焦点):灰色按钮 聚焦:黄色按钮 按下:黄色,顶部有深黄色波纹

实际发生的情况

默认(无焦点):灰色按钮 => 确定 聚焦:黄色,顶部有部分透明的深黄色 => 问题。 按下:深黄色波纹 => 确定

这种颜色混合似乎是波纹可绘制对象的默认行为,这使得它们实际上无法用于电视应用程序。

我有机会逃脱吗?我想要的基本上是一个不会修改背景颜色并且只在顶部绘制的波纹。

【问题讨论】:

我也遇到了同样的问题,你找到解决办法了吗?,我的重点部分也没有使用 D-Pad。 这里有同样的问题。有什么解决办法吗? 你找到解决办法了吗? 【参考方案1】:

根据https://***.com/a/29777616/332798,如果您为波纹添加一个遮罩,这将使默认状态透明并且不会再影响焦点颜色。

【讨论】:

【参考方案2】:

我知道这个问题已经很老了,但我找到了一个适合我的解决方案:

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

此行为的问题在于掩码项。 RippleDrawable 的文档说:

如果设置了遮罩层,波纹效果将在该层被绘制到其余子层的合成上之前被遮罩。

如果未设置遮罩层,则波纹效果将针对子层的合成进行遮罩。

据我了解,如果您使用 DPAD/HardKeys,那么掩码项目将获得焦点。为了排除遮罩项,我添加了一个选择器并用透明颜色覆盖了聚焦状态的行为。因此,如果视图聚焦,则遮罩将不可见。作为默认行为,必须为蒙版设置纯色,否则波纹将不可见。在我的例子中,我添加了一个形状,因为我希望我的波纹有圆角。

另外我为选择器添加了按下状态,因为我还想对硬键输入产生连锁反应。

最后,我添加了一个带有背景颜色的附加项目。

【讨论】:

以上是关于Android Ripple 可绘制和以状态为中心(DPAD 导航)的主要内容,如果未能解决你的问题,请参考以下文章

带有自定义可绘制xml的涟漪效应?

Android TV 按钮不显示焦点可绘制对象

Android自定义View实现可拖拽的进度条

如何处理 9-p​​atch 和 CardView 上的 Ripple 效果,并控制选择器的状态?

CSS transform:rotate();怎么设置旋转方向?比如向左上角旋转和以自身为中心放大

Lollipop 上的 Android Button Ripple 和 pre lollipop 上的高亮显示