我正在尝试为Android电视和Amazon FireTV应用程序中的按钮实现波纹效果背景(通过DPAD导航)。我使用的是AppCompat,但由于默认的按钮样式都使用波纹,我现在使用了一个自定义的可绘制背景,没有任何波纹,只有一个普通的选择器。
我试图实现的行为
- 默认(无焦点):灰色按钮
- 聚焦:黄色按钮
- 压制:黄色,顶部有深黄色波纹
实际发生了什么
- 默认(无焦点):灰色按钮=>确定
- 焦点:黄色,顶部为部分透明的深黄色=>问题
- 按下:暗黄色波纹=>OK
这种颜色混合似乎是波纹抽屉的默认行为,这使得它们实际上不适用于电视应用。
我有机会逃脱吗?我想要的基本上是一个波纹,不会修改背景颜色,只在顶部绘制。
根据https://stackoverflow.com/a/29777616/332798,如果你在波纹中添加一个遮罩,它将使默认状态透明,并且不会再影响聚焦的颜色。
我知道这个问题已经很老了,但我找到了一个适合我的解决方案:
<?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/HadKeys,那么掩码项目将成为焦点。为了排除掩码项,我添加了一个选择器,并用透明颜色覆盖聚焦状态的行为。因此,如果视图聚焦,遮罩将不可见。作为默认行为,必须为遮罩设置纯色,否则波纹将不可见。在我的例子中,我添加了一个形状,因为我想有圆角来形成波纹。
此外,我添加了选择器的按下状态,因为我想在硬键输入上也有波纹效果。
在最后一点上,我添加了一个带有我的背景色的附加项目。