I want to set an OnClickListener
on a RecyclerView
, not on its items so that it triggers a click event when the user clicks on the RecyclerView
(even if it is empty or full of items).
mRecyclerView.setClickable(true)
, not workingWhat I want
mRecyclerView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// do something
}
});
My Adapter Class
public class TaskItemAdapter extends RecyclerView.Adapter<TaskItemAdapter.BaseItemAdapterViewHolder> {
private static final String TAG = TaskItemAdapter.class.getSimpleName();
private List<Task> mTaskList;
private View.OnLongClickListener mOnLongClickListener;
public TaskItemAdapter(List<Task> taskList, View.OnLongClickListener longClickListener) {
mTaskList = taskList;
mOnLongClickListener = longClickListener;
}
@NonNull
@Override
public BaseItemAdapterViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (parent instanceof RecyclerView) {
int layoutId = R.layout.item_list_main;
View view = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
view.setFocusable(true);
return new BaseItemAdapterViewHolder(view);
} else {
throw new RuntimeException(TAG + "Not bound to recyclerView");
}
}
@Override
public void onBindViewHolder(@NonNull BaseItemAdapterViewHolder holder, int position) {
Task task = mTaskList.get(position);
holder.mItemTextView.setText("- " + task.getName());
holder.itemView.setTag(task);
holder.itemView.setOnLongClickListener(mOnLongClickListener);
}
@Override
public int getItemCount() {
return mTaskList.size();
}
public void loadItems(List<Task> taskList) {
mTaskList = taskList;
notifyDataSetChanged();
}
public class BaseItemAdapterViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.item_textView)
TextView mItemTextView;
public BaseItemAdapterViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
}
}
}
Where do you add the android:onClick attribute to make items in a RecyclerView respond to clicks? In the layout file that displays the RecyclerView, add it to the element. Add it to the layout file for an item in the row.
mRecyclerView.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() {
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
return true;
}
});
Then just handle the type of MotionEvent you want. Return true if you don't want the RecylerView doing anything else with it.
From View.OnTouchListener onTouch() press and release event. it is possible to trigger the views.
A RecyclerView
does not provide OnClick callbacks by default. So you can create an OnTouchListener to consume click events.
public class RVClickHandler implements View.OnTouchListener {
private RecyclerView mRecyclerView;
private float mStartX;
private float mStartY;
public RVClickHandler(RecyclerView recyclerView) {
mRecyclerView = recyclerView;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
boolean isConsumed = false;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
mStartX = event.getX();
mStartY = event.getY();
break;
}
case MotionEvent.ACTION_UP: {
float endX = event.getX();
float endY = event.getY();
if(detectClick(mStartX, mStartY, endX, endY)) {
//Ideally it would never be called when a child View is clicked.
//I am not so sure about this.
View itemView = mRecyclerView.findChildViewUnder(endX, endY);
if(itemView == null) {
//RecyclerView clicked
mRecyclerView.performClick();
isConsumed = true;
}
}
break;
}
}
return isConsumed;
}
private static boolean detectClick(float startX, float startY, float endX, float endY) {
return Math.abs(startX-endX) < 3.0 && Math.abs(startY-endY) < 3.0;
}
}
add this to your RecyclerView
as follows
recyclerView.setOnTouchListener(new RVClickHandler(recyclerView));
Now you can attach a normal OnClickListener to handle clicks.
recyclerView.setOnClickListener((v) -> {
//Called when an empty space is clicked inside RecyclerView.
});
Click events for child views can be handled inside the ViewHolder
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With