I have RecyclerView
and I set to each item OnTouchListener
and OnClickListener
OnTouchListener:
override fun onBindViewHolder(holder: ItemListViewHolder, position: Int) {
val item = getItem(position)
holder.bind(item)
holder.itemView.cardview.setOnTouchListener { v, event ->
if (event.action == MotionEvent.ACTION_DOWN) {
Log.d(TAG, "onBindViewHolder: $event.buttonState")
this.startDragListener.onStartDrag(holder)
}
return@setOnTouchListener true
}
}
OnClickListener:(inside the view holder)
init {
itemView.setOnClickListener(this)
}
override fun onClick(v: View?) {
onItemClickListener.onItemClick(adapterPosition)
}
The problem is when I click on the item, only the startDragListener
triggered, but the on click event never triggered.
I read some similar question on stackoverflow about this problem, but most of them are very old/deprecated method
How can I solve this problem and handle both touch listeners and click listeners?
See, onClickListener won't work with onTouchListener. You will have to implement some logic to differentiate between click and drag in onTouchListener. I did something like this, code is in java but you can get an idea.
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
x = motionEvent.getX();
y = motionEvent.getY();
return true;
case MotionEvent.ACTION_UP:
// PUT ON CLICK LOGIC HERE
break;
case MotionEvent.ACTION_MOVE:
if ((motionEvent.getX() - x) > 80 || (x - motionEvent.getX()) > 80
|| (motionEvent.getY() - y) > 50 || (y - motionEvent.getY()) > 60) {
view.startDrag(data, new View.DragShadowBuilder(view) {
@Override
public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
shadowSize.set(view.getWidth(), view.getHeight());
shadowTouchPoint.set((int) motionEvent.getX(), (int) motionEvent.getY());
}
}, view, 0);
}
return true;
}