231

我试图通过设置活动 XML 文件中的 android:backgound 属性来让 CardView 在触摸时显示涟漪效果,如Android开发人员页面上所述,但它不起作用。根本没有动画,但是调用了onClick中的方法。我也尝试按照这里的建议创建一个ripple.xml 文件,但结果相同。

CardView 出现在活动的 XML 文件中:

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="155dp"
    android:layout_height="230dp"
    android:elevation="4dp"
    android:translationZ="5dp"
    android:clickable="true"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:onClick="showNotices"
    android:background="?android:attr/selectableItemBackground"
    android:id="@+id/notices_card"
    card_view:cardCornerRadius="2dp">

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

我对android开发比较陌生,所以我可能犯了一些明显的错误。

4

13 回答 13

709

您应该将以下内容添加到CardView

android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"
于 2015-01-20T09:34:42.550 回答
26

我设法通过以下方式对cardview产生了连锁反应:

<android.support.v7.widget.CardView 
    xmlns:card_view="http://schemas.android.com/apk/res-auto" 
    android:clickable="true" 
    android:foreground="@drawable/custom_bg"/>

对于您可以在上面的代码中看到的 custom_bg,您必须为棒棒糖(在 drawable-v21 包中)和 pre-lollipop(在可绘制包中)设备定义一个 xml 文件。对于 drawable-v21 包中的 custom_bg,代码为:

<ripple 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?android:attr/colorControlHighlight">
<item
    android:id="@android:id/mask"
    android:drawable="@android:color/white"/>
</ripple>

对于drawable包中的custom_bg,代码为:

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

<item android:state_pressed="true">
    <shape>
        <solid android:color="@color/colorHighlight"></solid>
    </shape>
</item>
<item>
    <shape>
        <solid android:color="@color/navigation_drawer_background"></solid>
    </shape>
</item>
</selector>

因此,在棒棒糖之前的设备上,您将获得稳定的点击效果,而在棒棒糖设备上,您将在卡片视图上产生连锁反应。

于 2015-05-05T07:35:26.523 回答
16

您正在使用的 appcompat 支持库中省略了涟漪效应。如果您想查看涟漪效果,请使用 Android L 版本并在 Android L 设备上进行测试。根据 AppCompat v7 网站:

“为什么在之前的 Lollipop 上没有涟漪?让 RippleDrawable 顺利运行的很多原因是 Android 5.0 的新 RenderThread。为了优化以前版本的 Android 的性能,我们暂时不使用 RippleDrawable。”

在此处查看此链接以获取更多信息

于 2014-11-15T04:27:44.817 回答
12

如果minSdkVersion您正在使用的应用程序是 9 级,您可以使用:

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

相反,从第 11 级开始,您使用:

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

从文档:

clickable - 定义此视图是否响应点击事件。必须是布尔值,“真”或“假”。

foreground - 定义要在内容上绘制的可绘制对象。这可以用作叠加层。如果重力设置为填充,则前景可绘制对象参与内容的填充。

于 2016-09-21T12:56:34.410 回答
8

改用 Material Cardview,它扩展了 Cardview 并提供了多个新功能,包括默认的可点击效果:

<com.google.android.material.card.MaterialCardView>

...

</com.google.android.material.card.MaterialCardView>

依赖关系(它可以使用到 API 14 来支持旧设备):

implementation 'com.google.android.material:material:1.0.0'
于 2020-07-13T23:40:13.240 回答
6

对我来说,添加foregroundCardView不起作用(原因未知:/)

将相同的内容添加到它的子布局中就可以了。

代码:

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:focusable="true"
    android:clickable="true"
    card_view:cardCornerRadius="@dimen/card_corner_radius"
    card_view:cardUseCompatPadding="true">

    <LinearLayout
        android:id="@+id/card_item"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:foreground="?android:attr/selectableItemBackground"
        android:padding="@dimen/card_padding">

    </LinearLayout>
</android.support.v7.widget.CardView>
于 2017-07-11T10:25:54.113 回答
4

添加这两个类似的代码对于任何视图(如 Button、Linear Layout 或 CardView)来说都是一种魅力只需将这两行代码放在一起,看看它的神奇之处......

android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"
于 2018-05-22T13:21:00.710 回答
3

将以下内容添加到您的 xml:

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

并添加到您的适配器(如果是您的情况)

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val attrs = intArrayOf(R.attr.selectableItemBackground)
            val typedArray = holder.itemView.context.obtainStyledAttributes(attrs)
            val selectableItemBackground = typedArray.getResourceId(0, 0)
            typedArray.recycle()

            holder.itemView.isClickable = true
            holder.itemView.isFocusable = true
            holder.itemView.foreground = holder.itemView.context.getDrawable(selectableItemBackground)
        }
    }
于 2019-05-25T21:09:42.997 回答
2

androidCardview控制的波纹事件:

<android.support.v7.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:foreground="?android:attr/selectableItemBackground"
    android:clickable="true"
    android:layout_marginBottom="4dp"
    android:layout_marginTop="4dp" />
于 2016-01-04T08:42:02.523 回答
2

如果在 CardView 中存在像 RelativeLayout 或 LinearLayout 这样的根布局,其中包含适配器项的所有组件,则必须在该根布局中设置背景属性。像:

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="122dp"
android:layout_marginBottom="6dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
card_view:cardCornerRadius="4dp">

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/touch_bg"/>
</android.support.v7.widget.CardView>
于 2017-02-21T08:48:57.200 回答
2

对于那些在 RecyclerView 中显示的以编程方式创建的 CardView(或者在我的情况下扩展 CardView 的自定义视图)无法工作的涟漪效应问题的解决方案的人来说,以下内容对我有用。基本上,在 XML 布局文件中以声明方式声明其他答案中提到的 XML 属性似乎不适用于以编程方式创建的 CardView 或从自定义布局创建的CardView(即使根视图是 CardView 或使用了合并元素),所以它们必须像这样以编程方式设置:

private class MadeUpCardViewHolder extends RecyclerView.ViewHolder {
    private MadeUpCardView cardView;

    public MadeUpCardViewHolder(View v){
        super(v);

        this.cardView = (MadeUpCardView)v;

        // Declaring in XML Layout doesn't seem to work in RecyclerViews
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            int[] attrs = new int[]{R.attr.selectableItemBackground};
            TypedArray typedArray = context.obtainStyledAttributes(attrs);
            int selectableItemBackground = typedArray.getResourceId(0, 0);
            typedArray.recycle();

            this.cardView.setForeground(context.getDrawable(selectableItemBackground));
            this.cardView.setClickable(true);
        }
    }
}

这部分MadeupCardView extends CardView答案值得称赞TypedArray

于 2017-06-05T16:14:13.147 回答
1

我对 AppCompat 不满意,所以我编写了自己的 CardView 并向后移植了涟漪。在这里,它与 Gingerbread 一起在 Galaxy S 上运行,所以这绝对是可能的。

Galaxy S 上的 Ripple 演示

有关更多详细信息,请查看源代码

于 2015-05-09T09:26:43.440 回答
0
  android:foreground="?android:attr/selectableItemBackgroundBorderless"
   android:clickable="true"
   android:focusable="true"

仅工作 api 21 并使用它不使用此列表行卡片视图

于 2018-04-18T13:40:01.097 回答