向RecyclerView项添加涟漪效果

136

我正在尝试为RecyclerView的项添加涟漪效果。 我在网上搜索了一下,但没有找到我需要的内容。 我认为它必须是自定义效果。 我尝试使用android:background属性将其设置为“?android:selectableItemBackground”,但没有效果。

    <android.support.v7.widget.RecyclerView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:focusable="true"
    android:clickable="true"
    android:background="?android:selectableItemBackground"
    android:id="@+id/recyclerView"
    android:layout_below="@+id/tool_bar"/>

这是我正在尝试添加效果的RecyclerView:

在此输入图片描述


2
我将此问题重新打开,因为它不是this question的重复。尽管解决方案可能相似,但那个问题中有一些关于CardView的特定方面与这个更一般的问题无关。 - Suragch
@Suragch 谢谢您注意到了这个区别 :) - Georgi Koemdzhiev
6个回答

302

我找到解决方法了。我需要做的唯一一件事就是添加这个属性:

android:background="?android:attr/selectableItemBackground"

到我RecyclerView适配器填充的布局的根元素,就像这样:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingTop="8dp"
    android:paddingBottom="8dp"
    android:background="?android:attr/selectableItemBackground"
    tools:background="@drawable/bg_gradient">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="17sp"
        android:layout_marginLeft="15dp"
        android:layout_marginStart="15dp"
        android:id="@+id/shoppingListItem"
        android:hint="@string/enter_item_hint"
        android:layout_centerVertical="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"/>

    <CheckBox
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/shopping_list_item_checkbox_label"
        android:id="@+id/shoppingListCheckBox"
        android:layout_centerVertical="true"
        android:layout_marginRight="15dp"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:checked="false"/>

</RelativeLayout>

结果:

图片描述

如果你仍然无法看到涟漪效果,请将以下内容添加到布局的根元素中。

android:clickable="true"
android:focusable="true"

3
如果根元素是CardView,该怎么办? - Nabin
8
你应该把你的代码放在一个相对布局或线性布局里,然后再把它放到卡片布局里面。 - Sanved
7
@pronoobsanved,这对我很有帮助!对于那些仍然面临问题的人来说,CardView只接受一个布局作为其子项。针对该子项,将clickable和focusable属性设置为true,并将background属性设置为?attr/selectedableItemBackground。 - Vamsi Challa
49
对于CardView,将其设置为前景即可,即 android:foreground="?android:attr/selectableItemBackground" - Lorne Laliberte
7
我必须添加选项android:clickable="true",才能使其正常工作。 - Joaquin Iurchuk
显示剩余6条评论

92

如先前所述,最简单的解决方案是将以下内容之一添加为您的RecyclerView行的背景:

  • android:background="?android:attr/selectableItemBackground"
  • android:background="?attr/selectableItemBackground"

然而,如果您使用此方法遇到问题,或者想更细致地控制颜色,则可以执行以下操作。

自定义波纹效果

本答案以这个简单的Android RecyclerView示例开始。它将看起来像以下图像。

Ripple effect example GIF

为API 21以下的设备添加选择器

在API 21之前(Android 5.0 Lollipop),点击RecyclerView项只会更改其背景颜色(没有波纹效果)。这也是我们要做的。如果您仍有使用这些设备的用户,则他们已经习惯了这种行为,所以我们不会过多担心他们。(当然,如果您真的希望为他们提供涟漪效应,也可以使用自定义库。)

右键单击res/drawable文件夹,选择新建 > Drawable 资源文件。将其命名为custom_ripple。点击确定,并粘贴以下代码。

custom_ripple.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape android:shape="rectangle">
            <solid android:color="@color/colorAccent" />
        </shape>
    </item>
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@android:color/transparent" />
        </shape>
    </item>
</selector>

我在按下状态下使用colorAccent作为高亮颜色,因为它已经可用,但您可以定义任何颜色。

为API 21+设备添加涟漪效果

右键单击res/drawable文件夹,然后选择新建 > Drawable 资源文件。再次将其命名为custom_ripple。这一次不要点击OK。从可用限定符列表中选择版本,然后点击>>按钮并输入平台API级别21。现在点击确定并粘贴以下代码。

v21/custom_ripple.xml

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/colorAccent">

    <item
        android:id="@android:id/mask"
        android:drawable="@android:color/white" />
</ripple>

我再次使用colorAccent作为波纹颜色,因为它是可用的,但您可以使用任何您想要的颜色。遮罩将波纹效果限制在行布局中。遮罩颜色显然无关紧要,所以我只使用了不透明的白色。

设置为背景

在您的RecyclerView项目的根布局中,将背景设置为我们创建的自定义波纹。

android:background="@drawable/custom_ripple"

在我们开始的示例项目中,它看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:background="@drawable/custom_ripple"
    android:padding="10dp">

    <TextView
        android:id="@+id/tvAnimalName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"/>

</LinearLayout>

完成

这就是全部内容了。现在您应该能够运行您的项目了。感谢这个答案这个YouTube视频提供的帮助。


如果您想要一个默认的背景颜色,只需删除“android:id = "@ android:id/mask”这一行,然后将可绘制对象的颜色设置为您想要的任何颜色即可。 - Jordan Hochstetler

32

我认为有一个小细节被忽略了。

如果在添加android:background="?android:attr/selectableItemBackground"后仍然无法得到涟漪效果,请尝试在布局的根部添加以下几行代码。

android:clickable="true"
android:focusable="true"

这些将确保视图可点击,并启用上面提到的background属性的涟漪效果


8
将以下代码添加到您的适配器xml根视图中:
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"

5

使用按钮样式

这对我来说已经行之有效了很多次。

将无边框按钮样式添加到您布局的根元素中。 无需focusableclickable属性,因为默认样式已经包含了所有内容。

<androidx.constraintlayout.widget.ConstraintLayout
    style="@android:style/Widget.Material.Button.Borderless"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

@ededede 你可以使用min-height, max-height, width等XML属性来微调它,以适合你的需要。 - Favour Felix Chinemerem

4

一种简单且自定义的方法是按照这里所述设置视图主题。

some_view.xml

<ImageView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="?attr/selectableItemBackgroundBorderless"
   android:focusable="true"
   android:src="@drawable/up_arrow"
   android:theme="@style/SomeButtonTheme"/>

some_style.xml

<style name="SomeButtonTheme" >
   <item name="colorControlHighlight">@color/someColor</item>
</style>

这里可以找到其他自定义实现


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