使用selectableItemBackground和白色背景颜色

51
我一直在使用android:background="?selectableItemBackground"为视图(例如LinearLayout)添加涟漪效果。我记得在某个地方看到,这种方法向后兼容至API 14。
然而,我发现需要在白色背景上使用此涟漪效果。具体来说,我有一个列表项目布局,将显示在默认颜色背景上(我正在扩展Theme.AppCompat.Light.NoActionBar),因此我想通过将列表项涂成纯白色(#FFFFFF)来使其与该背景区分开来。
以下是列表项布局:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="?selectableItemBackground"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    ...

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:paddingLeft="@dimen/mdu_keyline_1"
        android:paddingRight="@dimen/mdu_keyline_1"
        android:paddingTop="@dimen/mdu_padding_normal"
        android:paddingBottom="@dimen/mdu_padding_normal">

        ...

    </LinearLayout>

</FrameLayout>

上述代码可以实现水波纹效果,但不带白色背景。
如果我尝试:
<FrameLayout ...
    android:background="@color/white">

这显然会产生一个白色背景,但没有涟漪效果。
我还尝试了其他方法 - 这产生了最接近我想要的结果:
<FrameLayout ...
    android:background="@color/white">

    ...

    <LinearLayout ...
        android:background="?selectableItemBackground">

上述代码给了我一个带有涟漪效果的白色背景。然而,无论我点击该项的哪个部分,涟漪似乎总是从中心开始。

以下是一些屏幕截图显示当前结果(请忽略列表项顶部的阴影 - 这是我正在使用的AppBarLayoutToolbar的阴影)。

enter image description here

enter image description here

我该如何实现所需效果?

4个回答

108

你可以使用 FrameLayout 的前景:

<FrameLayout ...
    android:background="@android:color/white"
    android:foreground="?attr/selectableItemBackground">

3
嗯,不知道为什么我以前从没听说过“foreground”。不过确实有效!谢谢! - EGHDK
2
注意,此功能仅适用于 API 23 及以上版本。对于较低版本,它将无效。 - Leo DroidCoder

36

您可以在drawable文件夹中创建一个layer-list,并将其设置为背景:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/white"/>
    <item android:drawable="?attr/selectableItemBackground"/>
</layer-list>

当我在drawable文件夹中使用ripple时,在Android 6.0上会导致错误,所以我创建了一个问题,请查看:binary-xml-file-line-error-inflating-class-unknown。你有尝试过在Android 6.0中采用这种方式吗? - Yasin Kaçmaz
当您将其用作背景可绘制项时(而不是前景),这种情况是否也会发生?我目前正在我的某个应用程序中使用上述完全相同的图层列表,它在Android 6上运行正常。我正在使用support libs 23.4.0。 - Marcel50506
在 CardView 中,您必须使用 android:foreground。 - Yasin Kaçmaz
刚刚将它应用到了 CardView 上作为前景,没有出现任何错误,我正在使用 Android 6。 - Marcel50506
很棒的解决方案! - Zakhar Rodionov
显示剩余3条评论

5
涟漪可绘制是一个LayerDrawable。 因此,正确的方法是:
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="?attr/colorControlHighlight">

    <item>
        <shape>
            <solid
                android:color="#FFFFFF"/>
        </shape>
    </item>

    <item android:id="@android:id/mask">
        <shape>
            <solid android:color="@android:color/white"/>
        </shape>
    </item>

</ripple>

5
其他答案也有一定作用,但是对于我来说,以下方法最好: 在styles.xml中添加colorControlHighlight。
  <style name="ExampleTheme" parent="Theme.AppCompat">
    <item name="colorAccent">...</item>
    <item name="colorPrimary">...</item>
    <item name="colorPrimaryDark">...</item>
    ...
    <item name="colorControlHighlight">@color/purple_bg</item> <-- THIS LINE
    ...
  </style>

</resources>

colors.xml中添加你喜欢的颜色,并加上一点透明度#77632E8E
<?xml version="1.0" encoding="UTF-8" ?>
<resources>

  <color name="purple_bg">#77632E8E</color>

</resources>

AndroidManifest.xml中设置你的活动主题(所有活动)。
<activity android:name=".MainActivity"
      ...
      android:theme="@style/ExampleTheme"
      ... />

在活动的布局文件 main_layout.xml 中,将 android:background 设置在您想应用效果的视图上:
<LinearLayout
    android:id="@+id/llBlock"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:background="?attr/selectableItemBackgroundBorderless">
    ....
</LinearLayout>

?attr/selectableItemBackground?attr/selectableItemBackgroundBorderless都可以工作。


只是一个小注释,主题可以应用于单个视图,例如 TextView,并且它将正确使用 colorControlHighlight 属性。 - abdu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接