RecyclerView + CardView + 触摸反馈

RecyclerView + CardView + Touch feedback

有人解开 CardViewRecyclerView 中时没有触摸反馈的谜团吗?

我有一个带有一堆 CardView 的 RecyclerView(CardList)。当我点击任何 CardView 时,我会启动另一个 Activity。这工作得很好,但是当我点击 CardView 时我看不到任何触摸反馈。

正好,我已经用这些配置了我的 CardView (XML):

android:clickable="true"
android:background="?android:selectableItemBackground"

谢谢!

背景:

CardView 忽略 android:background 支持只能是颜色的 app:cardBackground。边框和阴影实际上是背景的一部分,因此您不能自己设置。

解法:

使 CardView 内的布局可点击而不是卡片本身。您已经编写了此布局所需的两个属性:

android:clickable="true"
android:background="?android:selectableItemBackground"

创建选择器"drawable/card_foreground_selector"

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape android:shape="rectangle">
            <solid android:color="#18000000"/>
            <corners android:radius="@dimen/card_radius" />
        </shape>
    </item>
    <item android:state_focused="true" android:state_enabled="true">
        <shape android:shape="rectangle">
            <solid android:color="#0f000000"/>
            <corners android:radius="@dimen/card_radius" />
        </shape>
    </item>
</selector>

并创建 "drawable/card_foreground.xml"(您需要根据卡片的高度调整插入值

<inset xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/card_foreground_selector"
android:insetLeft="2dp"
android:insetRight="2dp"
android:insetTop="3dp"
android:insetBottom="3dp"/>

修改您的项目 (item.xml)

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:contentPadding="8dp"
    android:foreground="@drawable/card_foreground">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    // ..

    </LinearLayout>
</android.support.v7.widget.CardView>

可以查看原文posthere

解决方案 1

正如@Eugen 所建议的,您可以使 CardView 内的布局可点击,这样您就可以使用 android:background:

<android.support.v7.widget.CardView
    ...
    android:clickable="true"
    android:background="?attr/selectableItemBackground">

解决方案 2

如果您不想通过使 CardView 内的布局可点击而丢失项目点击监听器,您可以使用 android:foreground:

<android.support.v7.widget.CardView
    ...
    android:clickable="true"
    android:foreground="?attr/selectableItemBackground">

Extra:如果您不想要矩形遮罩,可以使用 "?attr/selectableItemBackgroundBorderless" 而不是 "?attr/selectableItemBackground"

添加foreground属性:

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

两种方法的工作方式应该相同。

1) 如果你想让 cardview 响应触摸反馈然后在 cardview[=46 中使用这个=].

 android:foreground="?android:attr/selectableItemBackground"
        android:clickable="true"
        android:focusable="true"

但如果上述方法不起作用,那么您可以在 child 视图组上设置此 属性 (Linear/Relative 等)cardview

   android:background="?android:attr/selectableItemBackground"
    android:clickable="true"
    android:focusable="true"

但是此时ViewHolder的itemView不会响应touch事件。由于它已被子视图消耗,因此您必须设置 clicklistener 在 childview 上进一步与 recyclerview 适配器中的侦听器一起工作,这样我们就可以在适配器中的 recyclerview 行项目上启用触摸和点击事件。

如果您很难跟随触摸并单击带有波纹的卡片视图中的视图,那么这可能会有所帮助。 Touch Feedback Problem

2.) 第二种方法是使用自定义触摸选择器可绘制并设置为背景的传统方式。

    <?xml version="1.0" encoding="utf-8"?>
<ripple
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="your ripple color">
    <item>
    <selector>
        <item android:state_selected="true">
            <color android:color="your selected color" />
        </item>
        <item android:state_activated="true">
            <color android:color="your selected color" />
        </item>
        <item>
            <color android:color="your normal color" />
        </item>
    </selector>
    </item>
</ripple>

文档Ripple Drawable