How to handle multiple layout clicks in recyclerView in Android

前端 未结 5 1731

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:34

    You can set listener into the adapter class. Here is the code :

    ViewHolder class inside adapter :

        public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    
        TextView textViewFirstName;
        ImageView imageViewProfile;
    
        public MyViewHolder(View view) {
            super(view);
            textViewFirstName = (TextView) view.findViewById(R.id.txtName);
            imageViewProfile = (ImageView) view.findViewById(R.id.imageViewProfile);
    
    //setOnClick
            view.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
        //check if the image you want to click should not invoke listener from activity/fragment
            if (v.getId() != R.id.imageViewProfile) {
                if (mItemClickListener != null) {
                    mItemClickListener.onItemClick(v, getPosition());
                }
            }
        }
    }
    

    Set your imageView click in Adapter class onBindViewHolder :

    @Override
    public void onBindViewHolder(MyViewHolder holder, final int position) {
    
        holder.textViewFirstName.setText(mArrayListTypeDetials.get(position).getFirstname());
        //set imageView click here
        holder.imageViewProfile.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               //ImageView clicked
            }
        });
    }
    

    Creating interface inside Adapter class :

    //interface for recyclerView item click
    public interface OnItemClickListener {
        void onItemClick(View view, int position);
    }
    
    /*
    method to set listener to the adapter ViewHolder item
     */
    public void setOnItemClickListener(final OnItemClickListener mItemClickListener) {
        this.mItemClickListener = mItemClickListener;
    }
    

    Setting interface from Activity/Fragment :

        mAdapter.setOnItemClickListener(new Adapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                Intent intent = new Intent(getActivity(), ABC.class);
                startActivity(intent);
            }
        });
    
    0 讨论(0)
  • 2021-01-02 10:42

    Handle the click in the adapter of your RecyclerView like below example:

    private class BookmarkViewHolder extends RecyclerView.ViewHolder {
    
            protected ImageView thumbnailIcon;
            protected TextView postTitle;
            protected TextView postViewCount;
    
            public BookmarkViewHolder(View v) {
                super(v);
    
                thumbnailIcon = (ImageView) v.findViewById(R.id.thumbnailIcon);
                postTitle = (TextView) v.findViewById(R.id.postTitleTV);
                postViewCount = (TextView) v.findViewById(R.id.viewCountTV);
    
                v.setOnClickListener(new OnClickListener() {
    
                    @Override
                    public void onClick(View v) {                                                
                    }
                });
    
                thumbnailIcon.setOnClickListener(new OnClickListener() {
    
                    @Override
                    public void onClick(View v) {                                                
                    }
                });
    
                postTitle.setOnClickListener(new OnClickListener() {
    
                    @Override
                    public void onClick(View v) {                                                
                    }
                });
    
    
            }
        }
    
    0 讨论(0)
  • 2021-01-02 10:45

    You may try this code :

    GestureDetector detector;
    

    then:

    detector = new GestureDetector(MainActivity.this, MainActivity.this);
    
        avatar.setOnTouchListener(new OnTouchListener() {
            public boolean onTouch(View view, MotionEvent e) {
                detector.onTouchEvent(e);
                return false;
            }
        });
    
    0 讨论(0)
  • 2021-01-02 10:51

    I tried this same way like @user320676, But I tried to complete with a Listener:

    interface MultipleClickListener {
            void onItemClickOne(int position, View v);
            void onItemClickTwo(int position, View v);
            void onItemClickThree(int position, View v);
    }
    

    then you can use the listener in a activity or fragment. Here you can see my full Adapter:

    public class MultipleClicksAdapter extends RecyclerView
            .Adapter<MultipleClicksAdapter
            .DataObjectHolder> {
    
        private ArrayList<MultipleClickData> mDataset;
        private static MultipleClickListener sClickListener;
    
        static class DataObjectHolder extends RecyclerView.ViewHolder {
    
            @BindView(R.id.multiple_clicks_one_textView)
            TextView mOne;
            @BindView(R.id.multiple_clicks_two_textView)
            TextView mTwo;
            @BindView(R.id.multiple_clicks_three_textView)
            TextView mThree;
    
            DataObjectHolder(View itemView) {
                super(itemView);
    
                ButterKnife.bind(this, itemView);
    
                mOne.setOnClickListener((View v) ->
                        sClickListener.onItemClickOne(getAdapterPosition(), mOne));
    
                mTwo.setOnClickListener((View v) ->
                        sClickListener.onItemClickTwo(getAdapterPosition(), mTwo));
    
                mThree.setOnClickListener((View v) ->
                        sClickListener.onItemClickThree(getAdapterPosition(), mThree));
            }
    
        }
    
        void setOnItemClickListener(MultipleClickListener myClickListener) {
            this.sClickListener = myClickListener;
        }
    
        MultipleClicksAdapter(ArrayList<MultipleClickData> myDataset) {
            mDataset = myDataset;
        }
    
        @Override
        public MultipleClicksAdapter.DataObjectHolder onCreateViewHolder(ViewGroup parent,
                                                                               int viewType) {
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.multiple_clicks_list_item, parent, false);
    
            MultipleClicksAdapter.DataObjectHolder dataObjectHolder = new MultipleClicksAdapter.DataObjectHolder(view);
            return dataObjectHolder;
        }
    
        @Override
        public void onBindViewHolder(MultipleClicksAdapter.DataObjectHolder holder, int position) {
            holder.mOne.setText(mDataset.get(position).getmTitle());
            holder.mTwo.setText(mDataset.get(position).getmSubTitle());
            holder.mThree.setText(mDataset.get(position).getmThirdTitle());
        }
    
        @Override
        public int getItemCount() {
            return mDataset.size();
        }
    
        interface MultipleClickListener {
            void onItemClickOne(int position, View v);
            void onItemClickTwo(int position, View v);
            void onItemClickThree(int position, View v);
        }
    
    }
    

    Also you can check the complete code in GitHub.

    0 讨论(0)
  • 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) {
    }
    

    }

    0 讨论(0)
提交回复
热议问题