我试图通过在活动 XML 文件中设置 android:backgound 属性来让 CardView 在触摸时显示波纹效果,如 Android 开发人员页面上的here所述,但它不起作用。根本没有动画,但是调用了onClick中的方法。我还尝试按照建议创建ripple.xml 文件here,但结果相同。
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 开发比较陌生,所以我可能犯了一些明显的错误。
您应该将以下内容添加到
CardView
:
android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"
我设法通过以下方式在卡片视图上获得连锁反应:
<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>
因此,在棒棒糖之前的设备上,您将获得稳定的点击效果,而在棒棒糖设备上,您将在卡片视图上产生连锁反应。
您正在使用的 appcompat 支持库中省略了连锁反应。如果您想查看波纹,请使用 Android L 版本并在 Android L 设备上进行测试。根据 AppCompat v7 网站:
“为什么预制棒棒糖上没有波纹? 让 RippleDrawable 能够流畅运行的很多因素就是 Android 5.0 新增的 RenderThread。为了优化以前版本的 Android 的性能,我们暂时将 RippleDrawable 排除在外。”
查看此链接此处了解更多信息
如果您正在使用的应用程序
minSdkVersion
是9级,您可以使用:
android:foreground="?selectableItemBackground"
android:clickable="true"
相反,从第 11 级开始,您可以使用:
android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"
来自文档:
clickable - 定义此视图是否对单击事件做出反应。必须是布尔值,“true”或“false”。
foreground - 定义在内容上绘制的可绘制对象。这可以用作叠加层。如果重力设置为填充,则前景可绘制对象会参与内容的填充。
改用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'
对我来说,将
foreground
添加到 CardView
不起作用(原因未知:/)
将相同的内容添加到其子布局中就可以了。
代码:
<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>
添加这两行类似的代码就像按钮、线性布局或 CardView 等任何视图的魅力一样,只需放置这两行即可看到魔力...
android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"
将以下内容添加到您的 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)
}
}
如果有像RelativeLayout或LinearLayout这样的根布局包含CardView中所有适配器项目的组件,则必须在该根布局中设置背景属性。喜欢:
<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>
对于那些寻找解决方案以解决在 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
部分。
Cardview
控制的
Ripple事件:
<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" />
android:foreground="?android:attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
仅工作 api 21 并使用此功能,而不使用此列表行卡视图
我对 AppCompat 不满意,所以我编写了自己的 CardView 和反向移植的 Ripples。这里它在 Galaxy S with Gingerbread 上运行,所以这绝对是可能的。
有关更多详细信息,请检查源代码。
如果您想要在卡片视图(子级)内有任何元素,您可以使用:
<ImageView
android:background="?android:attr/selectableItemBackground"
但是如果您需要整个卡片视图,请这样做:
android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
如果同时使用的话,颜色会比其他的深。
但是,最简单的方法是
com.google.android.material.card.MaterialCardView
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
为CardView添加上面的涟漪效果代码