RecyclerView嵌套RecyclerView,內層RecyclerView區域無法響應Item點擊長按

問題描述

項目中遇到了一個RecyclerView內嵌套RecyclerView,內層RecyclerView的區域無法響應所在Item的點擊事件的問題。
截圖如下,整個圖片部分是RecyclerView的一個Item,紅框所示商品圖片是內層的RecyclerView,這塊區域點擊無響應



解決方式(形式不同,原理相同)

方式一

viewHolder.rv.setOnTouchListener(new View.OnTouchListener() {
      @Override
      public boolean onTouch(View v, MotionEvent event) {
               return viewHolder.itemView.onTouchEvent(event);
      }
 });

給內層的RecyclerView設置OnTouchListener,在onTouch中處理外層RecyclerView的Item的觸摸事件onTouchEvent,item已經設置了點擊事件,所以在onTouchEvent的事件處理中會調用到item的點擊事件。

方式二

viewHolder.rv.setOnTouchListener(new View.OnTouchListener() {
     @Override
     public boolean onTouch(View v, MotionEvent event) {
          if(event.getAction() == MotionEvent.ACTION_UP){
              viewHolder.itemView.performClick();
          }
          return false;
     }
});

依然是給內層的RecyclerView設置OnTouchListener,在onTouch中調用外層RecyclerView的Item的preformClick方法,執行外層item的點擊事件。

方式三(其實就是把方式二加了些判斷封裝了下)

viewHolder.rv.setOnTouchListener(new ChildTouchListener(viewHolder.itemView));
public class ChildTouchListener implements View.OnTouchListener{

    private float downX;
    private float downY;
    private float touchSlop;
    private View view;

    public ChildTouchListener(View view){
        this.view = view;
        touchSlop = ViewConfiguration.get(view.getContext()).getScaledTouchSlop();
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getActionMasked()){
            case MotionEvent.ACTION_DOWN:
                downX = event.getX();
                downY = event.getY();
                break;
            case MotionEvent.ACTION_UP:
                if (Math.abs(event.getY() - downY) < touchSlop && Math.abs(event.getX() - downX) < touchSlop){
                    view.performClick();
                }
                break;
        }
        return false;
    }
}

依然是給內層的RecyclerView設置OnTouchListener,在onTouch中調用外層RecyclerView的Item的preformClick方法,執行外層item的點擊事件,就是加了些判斷。

總結

我們上面也說了,其實原理是相同的,裏面的RecyclerView區域點擊沒響應,是因爲RecyclerView內部重寫了onTouchEvent方法,導致了上述問題的發生,然後我們給RecyclerView設置OnTouchListener,那麼OnTouchListener中的onTouch方法會在onTouchEvent方法之前回調,並且需要注意onTouch方法的返回值,如果是false,onTouchEvent方法纔會被調用,如果是true,那麼onTouchEvent方法將不會被調用(也就是給view設置的OnTouchListener的優先級高於onTouchEvent),我們的處理中返回false以便不影響RecyclerView後續onTouchEvent中的固有邏輯。另外onTouchEvent方法中,如果當前View設置的有OnClickListener,那麼它的onClick方法會被調用,這也就是方法1中直接調用了itemView的onTouchEvent方法,自然後續會調用到我們設置的OnClickListener中的onClick方法,執行我們想要的業務邏輯。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章