【问题标题】:How to make a RecyclerView not clickable and pass onClick event to parent view?如何使 RecyclerView 不可点击并将 onClick 事件传递给父视图?
【发布时间】:2017-12-30 13:10:04
【问题描述】:

是否可以使RecyclerView 不可点击?我想要这个是因为我的RecyclerView 只是在可点击 CardView 中显示一些小图标。因此,如果有人点击图标,它应该只点击(并动画)父 CardView

我尝试了以下方法:

  1. recyclerView.setClickable(false);
  2. recyclerView.setFocusable(false);
  3. 扩展RecyclerView并使onTouchEvent(MotionEvent)返回false
  4. 使用上面的方法3,在RecyclerView适配器中使用itemView.setClickable(false);。这有效,点击被发送给父母。但是,现在RecyclerView 不再可滚动。
  5. 在膨胀的列表项 XML 中设置 clickable="false"focusable="false"focusableInTouchMode="false"。 (见评论 @Ibrahim
  6. 致电recyclerView#setLayoutFrozen(true)itemView.setClickable(false);。这可行,但与 #4 有相同的问题。

任何想法如何禁用RecyclerView 的点击事件并将其传递给父视图?请注意,RecyclerView 仍然需要可滚动(水平)。


编辑:
用户@c.dunlap 建议将 OnClick 侦听器设置为图标,并将单击“重定向”到父级的单击操作。这会起作用,但父视图上不会有点击动画。如果有人在 itemView 之外点击 - 但仍在 RecyclerView 内(例如 ItemDecoration 填充) - 则不会检测到点击。所以不幸的是,这不是一个解决方案。

【问题讨论】:

  • 适配器的代码是什么?
  • @VladoPandžić 适配器确实没有什么特别之处。它像往常一样膨胀布局。 onBindViewHolder(...) 中的唯一代码是将 Drawable 设置为 ImageView
  • 您是否尝试在膨胀的布局 xml 中设置 clickablefocusable 和 focusableontouchmode false?
  • @Ibrahim 刚试过,没用。
  • 还可以尝试 clickable="false"focusable="false"focusableInTouchMode="false" 进行回收xml ,如果可用则提供回收视图点击实现

标签: java android android-layout android-recyclerview


【解决方案1】:

你应该扩展父View并拦截点击,所以recyclerview不会收到它。

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    return true;
}

致谢:Solution

【讨论】:

  • 这是最好的解决方案。它应该被标记为答案
  • 这不会阻止在 RecyclerView 中滚动吗?
【解决方案2】:

我首选的处理此类事情的方法是从您的适配器附加一个侦听器,当您单击回收器视图中的每个图标时,该侦听器将被调用。然后您的活动可以以适当的方式响应。例如:

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private MyAdapterListener mListener;

    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
         holder.itemView.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 mListener.iconClicked();
             }
         });
    }

    public void setListener(MyAdapterListener listener) {
        mListener = listener;
    }

    public interface MyAdapterListener {
        void iconClicked();
    }

}

然后在您的活动中,您可以简单地创建一个 MyAdapterListener 实例并将其设置为您的 Recycler View 的适配器的侦听器。然后当iconClicked()函数被触发时,执行父点击会执行的代码。

【讨论】:

  • 感谢您的回答。这会起作用,但父视图上不会有点击动画。另外,如果有人在itemView 之外点击怎么办?我应该如何处理点击?
  • 请参阅我的问题的编辑部分。
  • 如果你修改你的 itemViews 使它们在回收站视图中没有任何间距,而是在 itemView 内部有填充,那么你的 itemViews 将填充 recyclerView 使其无法点击recyclerView 但不是项目视图。如果您正在做其他事情使这不可行,您可能需要共享您的布局,以便我们可以进一步帮助您。就个人而言,我发现这种方法通常也会导致更好的布局(单元格之间的间距均匀)。
  • 问题不在于itemViews之间有空间。就像你说的,我可以通过在 itemView 布局中使用填充来解决这个问题。问题是,如果只有几个“图标”,那么就不是整个 RecyclerView 都被使用了,还有剩余空间。我无法将 RecyclerView 设置为 wrap_content 因为它需要位于其他两个视图之间。因此,我认为您的回答不适用于我的情况。有其他解决方案的想法吗?
  • 你能分享你的布局吗?
【解决方案3】:

我有同样的问题,在我尝试了更多的东西之后,我在 recyclerview 上使用了一种布局。

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.v7.widget.RecyclerView
        android:layoutwidth="match_parent"
        android:layout_height="match_parent">
    </android.support.v7.widget.RecyclerView>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</RelativeLayout>

之后,您可以看到并消失“LinearLayout”。 这 100% 有效。

【讨论】:

  • 这是如何工作的?你能解释一下这是如何解决这个问题的吗?
  • 当你想让recyclerview不可用时,你可以让LinearLayout可见,当LinearLayout可行时recyclerview将不起作用,之后你可以去LinearLayout使recyclerview启用。
  • 好的,我明白了,但这不是我的问题。我的问题是如何禁用 RecyclerView and 将点击传递给父视图。我还注意到RecyclerView 仍然需要可滚动。如果我只是想禁用RecyclerView,我可以在RecyclerViewitemViews 上都使用setEnabled(false),但是点击不会传递给父布局。
  • 你能上传你的xml吗,我会给出正确的答案。
  • @ThomasVos 之所以有效,是因为 LinearLayout 掩盖了整个回收站视图,而是接收点击。
猜你喜欢
  • 2019-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-16
  • 1970-01-01
相关资源
最近更新 更多