使用RecyclerView和CardView触摸反馈

mik*_*enz 67 android touch-feedback android-cardview rippledrawable android-recyclerview

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

我创造了一个RecyclerView和一个CardView.该CardView包含不同的区域不同的onClick动作.现在,如果用户点击卡中的任何位置,我很乐意触发Ripple效果,但我无法实现此行为.

这是我的listitem,您也可以在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>
Run Code Online (Sandbox Code Playgroud)

并且onClick设置在此布局的3个部分上.libraryCreator,libraryDescriptionlibraryBottomContainer.

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

谢谢你的帮助.

Gak*_*ak2 120

假设您正在使用Material/Appcompat主题和Lollipop,我通过使CardView具有以下属性来实现此目的:

android:focusable="true"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground"
Run Code Online (Sandbox Code Playgroud)

  • 我猜你的问题是因为android:前景仅适用于FrameLayouts或继承FrameLayout的类,如CardView.如果您尝试在RelativeLayout或LinearLayout中设置它,它将无法正常工作 (23认同)
  • @ Gak2,我认为你需要设置`android:background而不是`android:foreground`.设置这个使它对我有用. (7认同)
  • 正如@AvinashR所说,设置android:background有效.然而,更好的增强是:`android:clickable ="true"android:background ="?attr/selectableItemBackground"`这样,背景使用前Lollipop设备上的默认触摸选择器和Lollipop及以上的漂亮波纹:-) (7认同)
  • 不,这不起作用:/.仍然没有点击反馈.只是在没有onClick监听器的区域 (2认同)

Avi*_*h R 52

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

android:background="?android:attr/selectableItemBackground"
Run Code Online (Sandbox Code Playgroud)

应该做的伎俩.

更新:

(看起来你正试图使用​​自定义波纹颜色.)

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

  • 我通过设置`android:focusable ="true"`和`android:clickable ="true"`来完成这个工作. (2认同)

cV2*_*cV2 22

为了我:

android:background="?android:attr/selectableItemBackground"
Run Code Online (Sandbox Code Playgroud)

让它终于奏效了.查看物品背后的recyclerView/content背景,还可以看到recyclelerView使用的涟漪效果.


Jja*_*ang 14

上述答案都不适合我,或者太复杂了.

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

android:background="?android:attr/selectableItemBackground"
android:focusable="true"
android:clickable="true"
Run Code Online (Sandbox Code Playgroud)

然后我开始工作了.


mik*_*enz 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

RippleForegroundListener rippleForegroundListener = new RippleForegroundListener();
older.libraryCreator.setOnTouchListener(rippleForegroundListener);
Run Code Online (Sandbox Code Playgroud)

此侦听器将通过触摸事件传递给CardView并触发正确的Ripple效果.(您也可以修改此视图以获取任何视图.它不应仅限于CardView)


sat*_*iva 9

android:foreground="?android:attr/selectableItemBackground"
Run Code Online (Sandbox Code Playgroud)

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


Saf*_*eer 5

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

android:background="@drawable/custom_bg"
android:foreground="?android:attr/selectableItemBackground"
Run Code Online (Sandbox Code Playgroud)