Weird RecyclerView behaviour onItemTouchListener

165 views Asked by At

I am trying to add RecyclerItemClickListener on my RecyclerView. It works fine, thing is my 2 components that are in my RecyclerView needs to be double clicked to execute their onClick action.

Here is my recyclerView.addOnItemTouchListener which is in my MainActivity:

recyclerView.addOnItemTouchListener(
            new RecyclerItemClickListener(this, recyclerView ,new RecyclerItemClickListener.OnItemClickListener() {
                @Override public void onItemClick(View view, final int pos) {
                    TextView sourceName = (TextView) view.findViewById(R.id.sourceName);
                    ImageView moreSettings = (ImageView) view.findViewById(R.id.moreSettings);

                    // Add on click listeners
                    sourceName.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            initiateDialogAlert(passObjArrayList.get(pos).getName(), passObjArrayList.get(pos).getPassword());
                            boiteAlerte.show();
                        }
                    });

                    moreSettings.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            createPopupMenu(view, pos);
                        }
                    });                        
                }
            });

How do I prevent this behaviour of needing to click twice on a component to execute his action?

My RecyclerItemClickListener:

public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;

public interface OnItemClickListener {
    public void onItemClick(View view, int position);

    public void onLongItemClick(View view, int position);
}

GestureDetector mGestureDetector;

public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
    mListener = listener;
    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) {
    View childView = view.findChildViewUnder(e.getX(), e.getY());
    if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
        mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
        return true;
    }
    return false;
}



public static boolean isViewClicked(View view, MotionEvent e) {
    Rect rect = new Rect();
    view.getGlobalVisibleRect(rect);
    return rect.contains((int) e.getRawX(), (int) e.getRawY());
}

@Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }

@Override
public void onRequestDisallowInterceptTouchEvent (boolean disallowIntercept){}
}
1

There are 1 answers

4
Pragnesh Ghoda  シ On

See there is difference between onTouch and onClick. And for recyclerview when you are handling onClick you have be code wisely.

Recyclerview don't give the functionality to us onClickListener by default. So you can create an interface and perform it.

Please refer below example to use onClickListener for recyclerview.

https://stand2code.blogspot.in/2016/12/recyclerview-item-onclicklistener.html

And you are returning true when your view is single tapped. Make sure that is this the problem maker or not ?

And if you want to perform different actions for different view onClicks. Try different interfaces there. It will help you from causing problems.

Sample Code :

public class ContentAdapter extends RecyclerView.Adapter<ContentAdapter.ViewHolder> {

    public interface OnItemClickListener {
        void onItemClick(ContentItem item);
    }

    private final List<ContentItem> items;
    private final OnItemClickListener listener;

    public ContentAdapter(List<ContentItem> items, OnItemClickListener listener) {
        this.items = items;
        this.listener = listener;
    }

    @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_item, parent, false);
        return new ViewHolder(v);
    }

    @Override public void onBindViewHolder(ViewHolder holder, int position) {
        holder.bind(items.get(position), listener);
    }

    @Override public int getItemCount() {
        return items.size();
    }

    static class ViewHolder extends RecyclerView.ViewHolder {

        private TextView name;
        private ImageView image;

        public ViewHolder(View itemView) {
            super(itemView);
            name = (TextView) itemView.findViewById(R.id.name);
            image = (ImageView) itemView.findViewById(R.id.image);
        }

        public void bind(final ContentItem item, final OnItemClickListener listener) {
            name.setText(item.name);
            Picasso.with(itemView.getContext()).load(item.imageUrl).into(image);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override public void onClick(View v) {
                    listener.onItemClick(item);
                }
            });
        }
    }
}