【问题标题】:How to handle click-event in RecyclerView.ItemDecoration?如何处理 RecyclerView.ItemDecoration 中的点击事件?
【发布时间】:2015-09-15 03:39:32
【问题描述】:

我有一个 RecyclerView(带有 LinearLayoutManager)和一个自定义的 RecyclerView.ItemDecoration。

假设我想在装饰视图中有按钮(出于某种原因..)。

我用按钮填充布局,它可以正确绘制。但我无法使按钮可点击。如果我按下它,什么都不会发生(它保持不变,没有按下效果)并且 onClick 事件不会触发。

ItemDecoration布局的结构是

<LinearLayout>
  <TextView/>
  <Button/>
</LinearLayout>

我正在尝试在装饰的 ViewHolder 中设置监听器

class ItemDecorationHolder extends RecyclerView.ViewHolder {
    public TextView header;
    public Button button;

    public HeaderHolder(View itemView) {
        super(itemView);

        header = (TextView)itemView.findViewById(R.id.header);
        button = (Button)itemView.findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //.. Show toast, etc.
            }
        });
    }
}

我正在 onDrawOver 方法中绘制装饰。 (其实我正在修改这个代码库:https://github.com/edubarr/header-decor

有什么想法吗?可行吗?

谢谢!

【问题讨论】:

    标签: android android-recyclerview android-viewholder


    【解决方案1】:

    正如尼尔所指出的,事情变得比这更复杂。但是根据定义,你不能。

    那么,为什么不包括能够做到这一点以及更多功能的优秀库呢? 我建议在我的FlexibleAdapter 项目中为可点击的粘性标题努力工作,该项目使用真实视图(而不是装饰器)来处理粘性标题上的点击事件。

    这部分还有一个工作演示和一个Wiki page(不仅如此)。

    【讨论】:

      【解决方案2】:

      除了Neil所说的, 这里的答案可能会有所帮助。 Passing MotionEvents from RecyclerView.OnItemTouchListener to GestureDetectorCompat

      然后你只需要计算标题的高度,看看点击是否落在该标题视图上并自己处理事件。

      private class RecyclerViewOnGestureListener extends GestureDetector.SimpleOnGestureListener {
          @Override
          public boolean onSingleTapConfirmed(MotionEvent e) {
              float touchY = e.getY();
      
      
      
              ALLog.i(this, "Recyclerview single tap confirmed y: " + touchY);
              //mGroupHeaderHeight is the height of the header which is used to determine whether the click is inside of the view, hopefully it's a fixed size it would make things easier here 
              if(touchY < mGroupHeaderHeight) {
                  int itemAdapterPosition = mRecyclerView.getLayoutManager().getPosition(mRecyclerView.findChildViewUnder(0, mGroupHeaderHeight));
      
                  //Do stuff here no you have the position of the item that's been clicked
                  return true;
              }
              return super.onSingleTapConfirmed(e);
      
          }
      
          @Override
          public boolean onDown(MotionEvent e) {
              float touchY = e.getY();
      
              if(touchY < mGroupHeaderHeight) {
                  return true;
              }
              return super.onDown(e);
          }
      
          @Override
          public boolean onSingleTapUp(MotionEvent e) {
              float touchY = e.getY();
      
              if(touchY < mGroupHeaderHeight) {
                  return true;
              }
              return super.onSingleTapUp(e);
          }
      }
      

      【讨论】:

        【解决方案3】:

        虽然真正的标题是从屏幕上滚动出来的,但可见的标题是直接在画布上绘制的,不像普通的交互式小部件。

        你有这些选择

        1. 重写 RecyclerView.onInterceptTouchEvent(),虽然有一些侵入性,所以我更喜欢下一个。
        2. 利用 RecyclerView.addOnItemTouchListener(),记住运动事件参数已经被转换为 RecyclerView 的坐标系。
        3. 使用真正的标题视图,但我认为这会走得有点远。

        如果选择选项 1/2,Button.setPressed(true) 并重绘表头会有视觉按下效果。

        【讨论】:

        • 在这种情况下,它将点击整个标题。如果我想点击标题上的特定位置,请提出建议。
        • 如果点击发生在标题中的特定“按钮”中,我如何触发事件?
        猜你喜欢
        • 2011-07-24
        • 1970-01-01
        • 1970-01-01
        • 2023-03-24
        • 2011-02-01
        • 2013-07-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多