How to handle multiple layout clicks in recyclerView in Android

前端 未结 5 1700

In our app we have list of messages. We are switching to RecyclerView. Our messages can consist from texts, images. Sample message can look like this.

5条回答
  •  走了就别回头了
    2021-01-02 10:59

    based on this post.

    //init listener
    rVDevicesList.addOnItemTouchListener(new  RecyclerItemClickListener(getContext(),
                rVDevicesList,
                this, R.id.tv_wonderful_item_share,  R.id.tv_wonderful_item_delete));  
    
    
    
    
    public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
    
    private OnItemClickListener mListener;
    private int[] extraIds;
    private Rect childRect = new Rect();
    
    public interface OnItemClickListener {
        void onItemClick(View view, int position);
    
        void onLongItemClick(View view, int position);
    }
    
    private GestureDetector mGestureDetector;
    
    /**
     * 
     * @param context
     * @param recyclerView
     * @param listener
     * @param ids: an alternative parameter
     */
    public RecyclerItemClickListener(Context context,
                                     final RecyclerView recyclerView,
                                     OnItemClickListener listener, final int... ids) {
        mListener = listener;
        extraIds = ids;
        mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }
    
            @Override
            public void onLongPress(MotionEvent e) {
                View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
                if (child != null && mListener != null) {
                    mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child));
                }
            }
        });
    }
    
    @Override
    public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
        final float x = e.getX();
        final float y = e.getY();
        Log.d("onInterceptTouchEvent", "onInterceptTouchEvent: " + x + " " + y);
        View childView = view.findChildViewUnder(e.getX(), e.getY());
        if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
            final int position = view.getChildAdapterPosition(childView);
            View target = getViewBy(childView, x, y, extraIds);
            //if target is non-null,so you click the view. 
            mListener.onItemClick(target, position);
            return true;
        }
        return false;
    }
    
    /**
     * find the view ,which view_rect contains the {x,y} in the window.
     * @param view: this view is  item layout view,may be a viewGroup
     * @param x
     * @param y
     * @param ids
     * @return true: hit a view which id in ids.
     */
    private View getViewBy(View view, float x, float y, int... ids) {
        if (ids == null || ids.length == 0 || !(view instanceof ViewGroup))
            return view;
        for (int i : ids) {
            View vChild = view.findViewById(i);
            if (vChild == null) {
                Log.d("onInterceptTouchEvent", "null");
            } else {
                int xy[] = new int[2];
                vChild.getLocationOnScreen(xy);
                childRect.left = xy[0];
                childRect.top = xy[1];
                childRect.right = xy[0] + vChild.getWidth();
                childRect.bottom = xy[1] + vChild.getHeight();
                boolean hit = childRect.contains((int) x, (int) y);
                Log.d("onInterceptTouchEvent", "find view: " + hit);
                if (hit)
                    return vChild;
            }
        }
        return view;
    }
    
    @Override
    public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
    
    }
    
    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
    }
    

    }

提交回复
热议问题