Android RecyclerView ViewHolder 拦截Touch事件

1,598 阅读1分钟

开发需求:标题Item 有title 还有说明 但是说明高度控制在8行高度 多出来的部分可以滚动查看

Android 控件ViewGroup 的事件分发机制 都是从上到下 分发拦截消费基于这个原理

具体实现 如下:

01.gif

 mRecyclerQuestionDView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
            @Override
            public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
                View view = rv.findChildViewUnder(e.getX(), e.getY());
                if (view != null) {
                    RecyclerView.ViewHolder viewHolder = rv.getChildViewHolder(view);
                    if (viewHolder instanceof QuestionDetailAdapter.HeaderViewHolder) {
 //返回是否拦截touch事件 
rv.requestDisallowInterceptTouchEvent(((QuestionDetailAdapter.HeaderViewHolder)
                                viewHolder).isTouchNsv(e.getRawX(), e.getRawY()));
                    }
                }
                return false;
            }

            @Override
            public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {

            }

            @Override
            public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

            }
        });
        
     /**
         * @param x event的rowX
         * @param y event的rowY
         * @return 这个点在不在 item 的范围内.
         */
        public boolean isTouchNsv(float x, float y) {
            int[] pos = new int[2];
            //获取sv在屏幕上的位置
            scrollV.getLocationOnScreen(pos);
            int width = scrollV.getMeasuredWidth();
            int height = scrollV.getMeasuredHeight();
            return x >= pos[0] && x <= pos[0] + width && y >= pos[1] && y <= pos[1] + height;
        }