I am trying to capture the clicks on ImageView
which is enclosed inside the RecyclerView
item. I have implemented RecyclerView.OnItemTouchListener
and has gesture detector process the motion events for normal clicks and long press on RecyclerView
item.
Since I want to have the same touch framework to process touch event on child views inside the RecylcerView
item, I have set View.OnTouchListener
with the image view as well, overriding the onTouch
implementation returning true hoping that the touch shall be consumed by the ImageView
when it gets clicked.
I am intentionally returning false in onInterceptTouchEvent
always from the RecyclerView
, hoping the child views process the event first and if none of them consumes then RecyclerView
's item view shall handle the gesture event for clicks during onTouchEvent
handling.
With the above understanding I am able to receive touch events on the ImageView
when clicked on it.
The problem is that, when I click on the RecyclerView
item outside ImageView
, RecyclerView
's onTouchEvent
is not getting called at all. my understanding of the touch framework is that if child views doesn't process the touch event, the RecyclerView
's onTouchEvent
should get a chance to process the same. However this is not what i am able to achieve.
Can anyone suggest what is happening behind and what is the correct way to process click events for the above?
This will solve your problem:
public class OnItemClickListener implements View.OnClickListener {
private int position;
private OnItemClickCallback onItemClickCallback;
public OnItemClickListener(int position, OnItemClickCallback onItemClickCallback) {
this.position = position;
this.onItemClickCallback = onItemClickCallback;
}
@Override
public void onClick(View view) {
onItemClickCallback.onItemClicked(view, position);
}
public interface OnItemClickCallback {
void onItemClicked(View view, int position);
}
}
Get an instance of 'OnItemClickCallback' interface and put it in your activity or fragment:
private OnItemClickListener.OnItemClickCallback onItemClickCallback = new OnItemClickListener.OnItemClickCallback() {
@Override
public void onItemClicked(View view, int position) {
// switch(view.getId()) ...
}
};
Then, pass that callback to your recyclerView:
recyclerView.setAdapter(new SimpleStringRecyclerViewAdapter(Arrays.asList("1", "2", "3"), onItemClickCallback));
Finally, this would be your adapter:
public class SimpleStringRecyclerViewAdapter extends RecyclerView.Adapter<SimpleStringRecyclerViewAdapter.ViewHolder> {
private List<String> mValues;
private OnItemClickListener.OnItemClickCallback onItemClickCallback;
public SimpleStringRecyclerViewAdapter(List<String> items, OnItemClickListener.OnItemClickCallback onItemClickCallback) {
mValues = items;
this.onItemClickCallback = onItemClickCallback;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
public final TextView mTextView;
public ViewHolder(View view) {
super(view);
mView = view;
mTextView = (TextView) view.findViewById(R.id.txt_title);
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.mTextView.setText(mValues.get(position));
holder.mView.setOnClickListener(new OnItemClickListener(position, onItemClickCallback));
holder.mTextView.setOnClickListener(new OnItemClickListener(position, onItemClickCallback));
}
@Override
public int getItemCount() {
return mValues.size();
}
}