使用 RecyclerView 和 CardView 触摸反馈 [英] Touch feedback with RecyclerView and CardView

查看:23
本文介绍了使用 RecyclerView 和 CardView 触摸反馈的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would love to enable touch feedback for my Open-Source library.

我创建了一个 RecyclerView 和一个 CardView.CardView 包含具有不同 onClick 操作的不同区域.现在,如果用户点击卡片中的任意位置,我很想触发 Ripple 效果,但我无法实现这种行为.

I've created a RecyclerView and a CardView. The CardView contains different areas with different onClick actions. Now I would love to trigger the Ripple effect if a user clicks anywhere in the card, but I'm not able to achieve this behavior.

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

This is my listitem, You can find it on GitHub too: 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 个部分上.libraryCreatorlibraryDescriptionlibraryBottomContainer.

And the onClick is set on 3 parts of this layout. libraryCreator, libraryDescription, and libraryBottomContainer.

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

I hope someone got an idea what is going wrong here.

感谢您的帮助.

推荐答案

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

I was now able to solve the issue.

问题是我在 TextViews 上使用了 onClickListener 并且这个点击监听器阻止了 RippleForeground 收到关于触摸事件的通知.所以解决方案是在这些 TextViews 上实现一个 TouchListener 并传递触摸事件.

The problem is that i use onClickListener on the TextViews and this click listener prevents the RippleForeground from being notified about the touch event. So the solution is to implement an TouchListener on those TextViews and pass through the touch event.

这个类真的很简单,到处都可以使用:

The class is really simple, and can be used everywhere:

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 来使用:

It can be used by adding this as TouchListener:

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

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

This listener will just pass through the touch event to the CardView and trigger the correct Ripple effect. (You can also modify this to take any view. It should not be limited to a CardView)

这篇关于使用 RecyclerView 和 CardView 触摸反馈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆