对Android Lollipop CardView的波纹效果


190

我试图让CardView时,通过设置在Android触摸显示连锁反应:活动XML文件中backgound属性描述这里 Android开发者页面上,但它不工作。完全没有动画,但是会调用onClick中的方法。我也尝试过按照这里的建议创建一个ripple.xml文件,但结果相同。

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

<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开发的新手,所以我可能犯了一些明显的错误。
提前致谢。

Answers:


591

您应将以下内容添加到CardView

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

8
适用于具有波纹效果的棒棒糖,但仅在较旧的平台上运行时才产生纯色。对我来说足够好了:)
mach

16
一些观察:我注意到clickable属性不是必需的,甚至可以破坏某些东西!我有一个GridView充满了可点击的CardView,并且侦听器无法正常工作。我从XML中删除了clickable标记,现在一切正常运行
Joaquin Iurchuk 2015年

2
@joaquin没有可点击的位置,它将导致波纹仅从中心产生
frostymarvelous

2
?android:attr/selectableItemBackground需要API级别11
Pratik Butani 2015年

9
没有工作android:clickable="true"
肖恩

30

将这两行代码添加到xml视图中,以对cardView产生波纹效果。

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

太棒了!foreground可与自定义背景视图一起使用,就像一个魅力!真好!
sud007

24

我设法通过以下方式对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,您必须为lollipop(在drawable-v21程序包中)和pre-lollipop(在drawable程序包中)设备都定义一个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>

因此,在棒棒糖之前的设备上,您将获得稳定的点击效果;在棒棒糖设备上,您将对Cardview产生连锁反应。


1
您好,我通过CardView的前景,它会阻止在CardView本身的孩子将选择(或波动)实现- stackoverflow.com/questions/33763403/...我可以知道你是否遇到相同的概率和我一样?或者,我会错过任何东西吗?谢谢。
Cheok Yan Cheng

@CheokYanCheng:我没有遇到像您这样的问题,但是从个人经验来看,cardView有一些棒棒糖之前的错误。避免在棒棒糖之前使用cardview:elevation属性。以上对我和其他支持者都有效。
Rahul Ahuja

我想知道,colorHighlight和navigation_drawer_background的值是多少。如果您使用自己定义的颜色而不设置透明度,那么您还能看到卡片的孩子吗?
Cheok Yan Cheng

@CheokYanCheng:值分别为<color name =“ navigation_drawer_background”>#FFFFFF </ color> <color name =“ colorHighlight”>#FF8A65 </ color>
Rahul Ahuja

我不为我的案子工作。我将您的选择器用作前景。不出所料,用作卡视图前景的纯白色(navigation_drawer_background)将阻止所有子级的可见性-i.imgur.com/CleYh5B.png这就是不将选择器用作前景-i.imgur的样子。 com / ZXk5Aoq.png
Cheok Yan Cheng

14

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

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

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


就是这样。谢谢!
AkraticCritic

39
但是您如何在Android Lollipop的cardView上施加连锁反应呢?
android开发人员

因此,我必须决定使用appcompat向后兼容性还是使用所有新效果(使用来自android核心的类,但仅限于API 21)?
Urs Reupke 2014年

您可以制作2个APK,一个21+,另一个2 <21。或者划分代码,因为21+不会使用supportActionbar等。听起来可能很麻烦,但是我相信这就是您的解决方案。
Mathijs Segers 2014年

1
这就是为什么目前无法编写“纯” Android L应用程序的原因。自2015年7月起,您将定位12%的Android用户群。
Glenn Bech 2015年

10

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

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

相反,从级别11开始,您可以使用:

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

从文档:

clickable-定义此视图是否对点击事件作出反应。必须为布尔值,“ true”或“ false”。

前景 -定义可绘制内容的可绘制对象。可以用作覆盖。如果重力设置为填充,则前景可绘制对象将参与内容的填充。


使用android:foreground =“?android:attr / selectableItemBackground”可实现AndroidX兼容性,谢谢!
dianakarenms

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>

2
这是因为孩子拦截了该事件,如果您尝试在cardview中添加填充(例如20dp之类),然后单击填充所在的部分,那么即使没有孩子,也会看到涟漪效应前景色属性集
Cruces

1
使用新的“材质组件”:com.google.android.material.card.MaterialCardView,这也对我有效。我为卡视图设置了一个高程stateListAnimator,以调整高程,并将涟漪图应用到前景中具有可选项目背景且没有clickable属性的内部约束布局。
Patty P

我现在不记得了,但是有一种方法可以将子视图设置为不对click事件做出反应
某处某人

3

将这两种类似的代码工作方式添加到按钮,线性布局或CardView等任何视图中,就像吸引人的魅力一样。只需将这两行放在一边,然后看一下魔术。

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

2

如果在CardView中有一个根布局,例如RelativeLayout或LinearLayout,其中包含适配器项的所有组件,则必须在该根布局中设置background属性。喜欢:

<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>

2

Android Cardview控制的涟漪事件:

<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" />

1

我对AppCompat不满意,所以我编写了自己的CardView并反向移植了涟漪。在这里,它可以在Galaxy S和Gingerbread上运行,因此绝对有可能。

Galaxy S上的涟漪演示

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


链接已断开
temirbek

1

将以下内容添加到您的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)
        }
    }

0

对于那些寻求解决涟漪效应问题的解决方案的人,如果在RecyclerView中显示的程序创建的CardView(或者在我的情况下为扩展CardView的自定义视图)中不起作用,以下方法对我有用。基本上,在XML布局文件中声明其他声明中提到的XML属性对于以编程方式创建的CardView或从自定义布局创建的CardView似乎不起作用(即使使用根视图是CardView或使用merge元素),因此必须像这样以编程方式设置它们:

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一部分。


0
  android:foreground="?android:attr/selectableItemBackgroundBorderless"
   android:clickable="true"
   android:focusable="true"

仅适用于API 21,并且使用此API不能使用此列表行卡视图

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.