【问题标题】:RecyclerView + CardView + Touch feedbackRecyclerView + CardView + 触控反馈
【发布时间】:2015-01-04 00:06:39
【问题描述】:

有没有人在 RecyclerView 内解决了没有触摸反馈的 CardView 之谜?

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

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

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

谢谢!

【问题讨论】:

标签: android touch android-5.0-lollipop android-recyclerview android-cardview


【解决方案1】:

背景:

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

解决方案:

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

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

【讨论】:

  • 嘿!对不起!你是对的。欺骗我的是我使用的是 Theme.Material 主题,它是一个“黑暗”主题。由于我已更改为 Theme.Material.Light,并使用了您的答案,因此发生了触摸反馈。
  • 这适用于 Lollipop 及更高版本。在 Kit Kat 上,内部视图的背景不会覆盖整个 cardView(在这里您可以意识到 Kit Kat 中的阴影是假的)。没关系,但并不完美。我现在可以忍受它。
  • 是的,我想我遇到了同样的问题。我不记得我是如何解决它的,但是将卡上的contentPadding 设置为与负cardCornerRadius 相同的值(准确地说是我认为的根值)应该完成一半的工作(确保设置@987654328 @ 到 true)。下半场是创建自定义背景<shape>STATEFUL!可绘制具有相同的角大小。第三部分是定义一个 drawable-v21,它使用涟漪代替。稍后我会尝试用示例更新答案。
  • android:foreground="?android:selectableItemBackground" on CardView 对我来说是一个更干净的解决方案,因为在 CardView 内设置可点击布局会禁用我的项目点击监听器
【解决方案2】:

解决方案 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">

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

【讨论】:

  • CardView 的前景是唯一适合我的解决方案。谢谢。
  • 此代码示例令人困惑 - CardView 中没有布局。如果它已经被卡片形状剪裁了,那么无边框选择器的意义何在?看起来一样。
【解决方案3】:

创建选择器“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>

您可以查看原帖here

【讨论】:

  • 我没有创建新的drawable,而是使用android:foreground="?android:selectableItemBackground"
  • @CarloRodríguez 这是 AppCompat 的“?selectableItemBackground”。它适用于所有平台吗?在 Lollipop 之前使用自定义可绘制对象,因为 ?selectableItemBackground 上的角没有被剪裁。
  • @EugenPechanec 你是对的,我没有意识到在 Lollipop 之前没有剪掉角落,如果卡片视图没有角落半径,它可能仍然是一个不错的选择。
【解决方案4】:

添加foreground属性:

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

【讨论】:

    【解决方案5】:

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

    1)如果您希望 cardview 响应触摸反馈,请在 cardview 中使用这个。

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

    但如果上述方法不起作用,那么您可以在 cardviewchild 视图组(线性/相对等)上设置此属性。

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

    但随后 ViewHolder 的 itemView 将不会响应 touch 事件。因为它已被子视图消耗,因此您必须在子视图上设置 clicklistener,以便在监听器中进一步处理recyclerview 适配器,这样我们就可以在适配器中的 recyclerview 的行项目上启用触摸和点击事件。

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

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

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

    【讨论】:

      猜你喜欢
      • 2015-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-10
      相关资源
      最近更新 更多