将波纹效果设置为 RecyclerView CardView 项目,而无需双击项目操作

Setting Ripple effect to RecyclerView CardView item without having to double tap for an item action

我有一个 RecyclerView 和一个 CardView 作为行项目布局的根元素。我设法使用下面的列表项布局对 CardView 产生连锁反应 here

行项目布局:

<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/margin_8dp"
    android:background="?android:attr/selectableItemBackground"
    android:clickable="true"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:foreground="?android:attr/selectableItemBackground"
    app:cardBackgroundColor="@color/cyan"
    app:cardCornerRadius="20dp"
    app:cardElevation="5dp">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/transparent"
        android:padding="@dimen/margin_8dp">

            <!-- Underlying views-->

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.cardview.widget.CardView>

问题是要在 RecyclerView 适配器中对行项目进行点击操作需要点击几次,第一次点击用于选择项目并显示涟漪效果,第二次点击用于实际点击触发 View.OnClickListener.

CardView中使用android:focusableInTouchMode = "true"属性是双击的原因;但禁用它,也会相应地禁用涟漪效应。

我尝试使用 this answer, but doesn't work. Also tried to have the ripple effect on the underlying CardView root element as in 中的自定义波纹效果,但仍然没有新内容。

使用按钮样式与 here 类似。

而且我在视图持有者的 RecyclerView 适配器中有一个跨国 itemView 点击监听器

class ViewHolder extends RecyclerView.ViewHolder {

    ViewHolder(@NonNull final View itemView) {
        super(itemView);

        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });
     }
}

View.OnClickListener 替换为 View.OnFocusChangeListener,当行项目在单击后获得焦点时,我 运行 使用与 onClick 回调中相同的代码。

但这并没有让涟漪效应出现的机会,所以延迟发布。

itemView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus)
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    // Do whatever done in onClick()
                }
            }, 10); // delay to give the ripple effect a chance to show
    }

});

如果有其他解决方案,我希望不会有任何延迟。

我通过从 CardView 中完全删除 android:focusableInTouchMode = "true"android:foreground 并使用 android:background="?android:attr/selectableItemBackground"[= 在 CardView 的根项中添加波纹效果来解决这个问题15=]

<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/margin_8dp"
    app:cardBackgroundColor="@color/cyan"
    app:cardCornerRadius="20dp"
    app:cardElevation="5dp">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?android:attr/selectableItemBackground"
        android:padding="@dimen/margin_8dp">

            <!-- Underlying views-->

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.cardview.widget.CardView>