Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setOnClickListener for recyclerView not working

For RecyclerView if it has not any item, then click on RecyclerView works, but if it has items clicking on RecyclerView doesn't work. Be careful I mean click on just RecyclerView not RecyclerView's item

recyclerView.setOnClickListener(view -> {Timber.d("recyclerView clicked");});

How I can set RecyclerView clickable even it has items on it.

like image 560
Mehrdad Faraji Avatar asked Dec 23 '22 15:12

Mehrdad Faraji


2 Answers

Try to extend RecyclerView and Override onInterceptTouchEvent. Also make it always return true. Then use OnTouch instead of OnClickListener Here are some of code.

public class MyRecyclerView extends RecyclerView {
    public MyRecyclerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        return true;
    }
}

Activity.class

recyclerView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
 Toast.makeText(MainActivity.this,"RecyclerView",Toast.LENGTH_SHORT).show();
            return false;
        }
    });
like image 76
leo liao Avatar answered Dec 27 '22 01:12

leo liao


TL;DR Java

recyclerView.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_UP)
            return view.performClick();
        else
            return false;
    }
});

recyclerView.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
        // do something
    }
});

TL;DR Kotlin

recyclerView.setOnTouchListener { view, motionEvent ->
    if (motionEvent.action == MotionEvent.ACTION_UP)
        view.performClick()
    else
        false
}

recyclerView.setOnClickListener { view ->
    // do something
}

Explanation (Java)

When the user touches the screen, the OnTouchListener of the topmost view is triggered. Its purpose is to detect gestures (tap, long tap, swipe, etc.) and call the respective handlers. A simple tap, for example, should result in a call to the OnClickListener.

Now, for some reason, RecyclerView does not do that (at least it does not watch for the tap gesture) - maybe because the developers did not intend the RecyclerView to be tapped as a whole.

So, we implement the OnTouchListener ourselves. The easiest way would be implementing the click logic in the OnTouchListener itself and return true to keep the event from propagating further up in the view hierarchy:

recyclerView.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        // do something
        return true
    }
});

However, as the OnTouchListener is usually invoked multiple times during a single tap on the screen, we should run our code only once after the last touch event. Furthermore, the business logic should go into the OnClickListener which is called by performClick() (that returns true afterwards):

recyclerView.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_UP)
            return view.performClick();
        else
            return false;
    }
});

recyclerView.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
        // do something
    }
});
like image 28
Tobias Uhmann Avatar answered Dec 27 '22 02:12

Tobias Uhmann