处理 RecyclerView 项目的点击事件和项目内按钮的点击事件。避免同时听两者
Posted
技术标签:
【中文标题】处理 RecyclerView 项目的点击事件和项目内按钮的点击事件。避免同时听两者【英文标题】:Handling click events of a RecyclerView Item and the click events of buttons inside the item. Avoid listening to both at the same time 【发布时间】:2020-11-19 04:06:19 【问题描述】:我有一个带有按钮的 recyclerview 项目。
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_margin="1dp">
<LinearLayout
android:layout_
android:layout_
android:padding="1dp">
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical"
android:layout_weight="1"
android:id ="@+id/layLeft">
<TextView
android:id="@+id/txtName"
android:layout_
android:layout_
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:layout_marginTop="2dp"
android:textColor="@android:color/black" />
<TextView
android:id="@+id/txtDesc"
android:layout_
android:layout_
android:layout_marginStart="2dp"
android:layout_marginLeft="2dp"
android:layout_marginTop="2dp"
android:layout_marginRight="2dp"
android:ellipsize="end"
android:maxLines="1" />
<TextView
android:id="@+id/txtCategory"
android:layout_
android:layout_
android:layout_marginLeft="2dp"
android:layout_marginStart="2dp"
android:layout_marginTop="2dp"
android:textColor="@android:color/holo_red_dark" />
</LinearLayout>
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical"
>
<ImageButton
android:id="@+id/btn_mark_done"
android:layout_
android:layout_
android:background="@null"
android:padding="4dp"
android:src="@android:drawable/ic_menu_set_as"
android:layout_centerHorizontal="true"
android:adjustViewBounds="true"
android:scaleType="fitXY"/>
<ImageButton
android:id="@+id/btn_delete"
android:layout_
android:layout_
android:background="@null"
android:padding="4dp"
android:src="@android:drawable/ic_menu_delete"
android:layout_centerHorizontal="true"
android:adjustViewBounds="true"
android:scaleType="fitXY"/>
</LinearLayout>
</LinearLayout>
</FrameLayout>
为处理 RecyclerView 项目和单个按钮的单击事件创建了一个自定义侦听器。单击按钮时,单击事件侦听器可以正常工作。而且 RecyclerView itemclick 监听器也被监听。这会导致双重执行。
下面给出了监听器
class RecyclerTouchListener implements RecyclerView.OnItemTouchListener
private ClickListener clicklistener;
private GestureDetector gestureDetector;
public RecyclerTouchListener(Context context, final RecyclerView recycleView, final ClickListener clicklistener)
this.clicklistener=clicklistener;
gestureDetector=new GestureDetector(context,new GestureDetector.SimpleOnGestureListener()
@Override
public boolean onSingleTapUp(MotionEvent e)
return true;
@Override
public void onLongPress(MotionEvent e)
View child=recycleView.findChildViewUnder(e.getX(),e.getY());
if(child!=null && clicklistener!=null)
clicklistener.onLongPress(recycleView.getChildAdapterPosition(child));
);
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e)
View child=rv.findChildViewUnder(e.getX(),e.getY());
if(child!=null && clicklistener!=null && gestureDetector.onTouchEvent(e))
clicklistener.launchIntent(rv.getChildAdapterPosition(child));
return false;
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e)
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept)
对于按钮
btnMarkDone.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
clickListener.onMarkDone( 0);
);
btnDelete.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
clickListener.onDeleteItem( 0);
);
有什么办法可以避免吗?
【问题讨论】:
【参考方案1】:我猜你应该尽量避免实现 RecyclerView.OnItemTouchListener,请按如下方式使用带有适配器的回收视图并在 recycleView 项目单击时使用 TouchListener,代码如下 -
public class RecycleAdapter extends RecyclerView.Adapter<RecycleAdapter.CustomViewHolder>
private Context context;
// your data variables
public RecycleAdapter(Context context)
this.context = context;
// implement your click and touch listeners here
@NonNull
@Override
public CustomViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
return new CustomViewHolder(LayoutInflater.from(context).inflate(R.layout.item_layout, parent, false));
@Override
public void onBindViewHolder(@NonNull CustomViewHolder holder, int position)
//data binding code
@Override
public int getItemCount()
// return size;
public class CustomViewHolder extends RecyclerView.ViewHolder
ImageView btnMarkDone, btnMarkDone;
public CustomViewHolder(@NonNull View itemView)
super(itemView);
btnMarkDone = itemView.findViewById(R.id.btnMarkDone);
btnMarkDone = itemView.findViewById(R.id.btnMarkDone);
btnMarkDone.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
// click listener here
);
btnDelete.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
// click listener here
);
itemView.setOnTouchListener(new View.OnTouchListener()
@Override
public boolean onTouch(View v, MotionEvent event)
//implement touch listener action here
return false;
);
如果您想对回收视图滚动进行操作,那么用户 RecyclerView.OnScrollListener
编码愉快!
【讨论】:
以上是关于处理 RecyclerView 项目的点击事件和项目内按钮的点击事件。避免同时听两者的主要内容,如果未能解决你的问题,请参考以下文章
RecyclerView | 处理 RecyclerView 中的点击事件
RecyclerView | 处理 RecyclerView 中的点击事件