67

我很想为我的开源库启用触摸反馈。

我创建了一个RecyclerView和一个CardViewCardView包含具有不同onClick动作的不同区域。现在,如果用户单击卡片中的任何位置,我很想触发涟漪效应,但我无法实现这种行为。

这是我的列表项,你也可以在 GitHub 上找到它:https ://github.com/mikepenz/AboutLibraries/blob/master/library/src/main/res/layout/listitem_opensource.xml

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clickable="true"
    android:background="@drawable/button_rect_normal"/>

<LinearLayout
    android:padding="6dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <LinearLayout
        android:gravity="center_vertical"
        android:paddingLeft="8dp"
        android:paddingRight="8dp"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/libraryName"
            android:textColor="@color/title_openSource"
            android:textSize="@dimen/textSizeLarge_openSource"
            android:textStyle="normal"
            android:layout_width="0dp"
            android:layout_weight="5"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:maxLines="1"/>

        <TextView
            android:id="@+id/libraryCreator"
            android:textColor="@color/text_openSource"
            android:textStyle="normal"
            android:layout_width="0dp"
            android:layout_weight="2"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:gravity="right"
            android:maxLines="2"
            android:textSize="@dimen/textSizeSmall_openSource"/>
    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:layout_marginTop="4dp"
        android:background="@color/dividerLight_openSource"/>

    <TextView
        android:id="@+id/libraryDescription"
        android:textSize="@dimen/textSizeSmall_openSource"
        android:textStyle="normal"
        android:textColor="@color/text_openSource"
        android:padding="8dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:maxLines="20">
    </TextView>

    <View
        android:id="@+id/libraryBottomDivider"
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:layout_marginTop="4dp"
        android:background="@color/dividerLight_openSource"/>

    <LinearLayout
        android:id="@+id/libraryBottomContainer"
        android:gravity="center_vertical"
        android:paddingLeft="8dp"
        android:paddingTop="4dp"
        android:paddingRight="8dp"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/libraryVersion"
            android:textColor="@color/text_openSource"
            android:textStyle="normal"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:gravity="left"
            android:maxLines="1"
            android:textSize="@dimen/textSizeSmall_openSource"/>

        <TextView
            android:id="@+id/libraryLicense"
            android:textColor="@color/text_openSource"
            android:textStyle="normal"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:gravity="right"
            android:maxLines="1"
            android:textSize="@dimen/textSizeSmall_openSource"/>
    </LinearLayout>
</LinearLayout>

并且onClick设置在此布局的 3 个部分上。libraryCreator, libraryDescription, 和libraryBottomContainer.

我希望有人知道这里出了什么问题。

谢谢你的帮助。

4

10 回答 10

123

假设您使用的是 Material/Appcompat 主题和 Lollipop,我通过使 CardView 具有以下属性来实现这一点:

android:focusable="true"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground"
于 2014-11-17T15:12:11.930 回答
52

CardLayout 只是 ViewGroup 的子类,所以设置:

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

应该做的伎俩。

更新:

(看起来您正在尝试使用自定义波纹颜色。)

尝试使用带有自定义颜色的可绘制波纹作为背景(我没有使用过这个,所以我无法验证这种行为。)请参阅:文档或此问题以帮助您入门。

于 2014-12-26T20:40:53.123 回答
22

为了我:

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

让它终于工作了。查看 recyclerView 的背景 / 项目后面的内容,还可以查看与 recyclerView 一起使用的涟漪效果。

于 2015-03-13T13:23:56.003 回答
14

以上答案都不适合我,或者太复杂了。

然后我意识到我必须在 RECYCLERVIEW ADAPTER LAYOUT 中设置以下属性。

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

然后我开始工作了。

于 2015-09-13T17:16:19.837 回答
10

我现在能够解决这个问题。

问题是我在 TextViews 上使用了 onClickListener,而这个点击监听器阻止了 RippleForeground 收到有关触摸事件的通知。所以解决方案是在那些 TextView 上实现一个 TouchListener 并通过触摸事件。

该类非常简单,并且可以在任何地方使用:

package com.mikepenz.aboutlibraries.util;

import android.support.v7.widget.CardView;
import android.view.MotionEvent;
import android.view.View;

/**
 * Created by mikepenz on 16.04.15.
 */
public class RippleForegroundListener implements View.OnTouchListener {
    CardView cardView;

    public RippleForegroundListener setCardView(CardView cardView) {
        this.cardView = cardView;
        return this;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // Convert to card view coordinates. Assumes the host view is
        // a direct child and the card view is not scrollable.
        float x = event.getX() + v.getLeft();
        float y = event.getY() + v.getTop();

        if (android.os.Build.VERSION.SDK_INT >= 21) {
            // Simulate motion on the card view.
            cardView.drawableHotspotChanged(x, y);
        }

        // Simulate pressed state on the card view.
        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                cardView.setPressed(true);
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                cardView.setPressed(false);
                break;
        }

        // Pass all events through to the host view.
        return false;
    }
}

可以通过将其添加为 TouchListener 来使用它:

RippleForegroundListener rippleForegroundListener = new RippleForegroundListener();
older.libraryCreator.setOnTouchListener(rippleForegroundListener);

这个监听器只会将触摸事件传递给 CardView 并触发正确的 Ripple 效果。(您也可以修改它以获取任何视图。不应仅限于 CardView)

于 2015-04-24T22:17:12.483 回答
9
android:foreground="?android:attr/selectableItemBackground"

如果您使用前景而不是背景,则不需要使用可点击或可聚焦

于 2016-05-06T07:54:21.750 回答
5

就我而言,我还需要显示自定义背景和涟漪效果。所以我实现这一点的方法是在我的 recycler-view 项目的根布局上应用这两个属性:

android:background="@drawable/custom_bg"
android:foreground="?android:attr/selectableItemBackground"
于 2017-05-27T12:27:48.520 回答
4

和蒋有同样的问题:

我必须将属性设置为布局文件,这会使 RecycleView 膨胀。

我的主布局:(不要在此处添加属性!)

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">


<android.support.v7.widget.RecyclerView
    android:id="@+id/recycler_view"
    android:scrollbars="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

</RelativeLayout>

我的 RecycleViewAdapter:

            View v = inflater.inflate(R.layout.list_center_item, parent, false);

我的 list_center_item.xml(在此处添加属性!

<?xml version="1.0" encoding="utf-8"?>


<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"


android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
/>
于 2016-08-31T13:29:40.670 回答
0

在我的情况下,实际的愚蠢问题如下......

从技术上讲,情况并非像每个人在我的案例中所建议的那样。真正的问题是你不应该在LayoutView,RelativeViewTextView.

它应该只在 CardView 中。 然后它就像魅力一样

android:focusable="true"不是真的需要。

只需在您的 CardView 中添加以下内容

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


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <android.support.v7.widget.CardView
        android:id="@+id/card_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:layout_margin="@dimen/card_margin"
        android:foreground="?android:attr/selectableItemBackground"
        android:clickable="true"
        android:elevation="3dp"
        card_view:cardCornerRadius="@dimen/card_corner_radius">

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

            <ImageView
                android:id="@+id/card_template_item_image"
                android:layout_width="match_parent"
                android:layout_height="@dimen/card_size_height"
                android:scaleType="fitXY" />

            <TextView
                android:id="@+id/card_template_item_title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/card_template_item_image"
                android:paddingLeft="@dimen/card_title_padding"
                android:paddingRight="@dimen/card_title_padding"
                android:paddingTop="@dimen/card_title_padding"
                android:textSize="@dimen/card_title_size"
                android:text="@string/place_holder_item_name"/>

            <TextView
                android:id="@+id/card_template_item_sub_title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/card_template_item_title"
                android:paddingBottom="@dimen/card_sub_title_padding"
                android:paddingLeft="@dimen/card_sub_title_padding"
                android:paddingRight="@dimen/card_sub_title_padding"
                android:textSize="@dimen/card_sub_title_size"
                android:text="@string/place_holder_item_category"/>

        </RelativeLayout>

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

</LinearLayout>
于 2018-10-17T11:19:36.603 回答
0

您必须在您正在使用的布局中添加以下行CardView

android:clickable="true"
android:focusable="true"
android:background="@drawable/my_ripple"

例子

<android.support.v7.widget.CardView android:layout_height="wrap_content"
android:layout_width="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:background="@drawable/my_ripple">
于 2017-02-07T17:27:42.423 回答