RecyclerView的点击事件处理求教
1个回答
展开全部
RecyclerView本身并没有提供用于监听Item点击、长按等事件的方法,需要我们自己实现来进行监听。
通常实现监听的方法有两种:
通过在Adapter中设置监听回调来处理点击逻辑
通过设置RecyclerView.addOnItemTouchListener,并重写RecyclerView.OnItemTouchListener来实现
在Adapter中设置回调
实现逻辑跟我们平常设置监听回调的逻辑并无差别:
1.定义一个MyClickListener接口,并定义onClick()、onLongClick()等回调方法
2.在Adapter中定义一个MyClickListener对象,并提供设置方法setOnMyClickListener或者在构造方法中指定MyClickListener对象参数
3.在Adapter的onBindViewHolder中给View设置监听setOnclickListener和setOnLongClickLister等
4.Activity中进行回调,处理点击逻辑
代码:
public MyRecyclerViewAdapter(Context mContext, List<Integer> datas, MyOnClickListeneronClickListener){
this.mContext = mContext;
this.datas= datas;
this.onClickListener= onClickListener;
}
public void setOnclickListener(MyOnClickListener onClickListener){
this.onClickListener = onClickListener;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
((MyViewHolder)holder).mImageView.setImageResource(datas.get(position));
((MyViewHolder)holder).rootView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v){
if(onClickListener != null){
onClickListener.onClick(v, position);
}
}
});
((MyViewHolder)holder).rootView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if(onClickListener != null){
onClickListener.onLongClick(v, position);
}
return true;
}
});
}
/**
* 点击监听接口
*/
public interface MyOnClickListener{
void onClick(View view, int position);
void onLongClick(View view, int position);
}
在Activity中:
vRecyclerView.setAdapter(new MyRecyclerViewAdapter(this, datas, new MyOnClickListener() {
@Override
public void onClick(Viewview, int position) {
//点击
}
@Override
public void onLongClick(Viewview, int position) {
//长按
}
}));
这种实现方式的突出有点就是简单明了,易于实现。但是这种实现方式首先违背了但一直责原则,再者其与Adapter高度耦合的特点也决定了他的复用性比较低。比如:现在有多个不同的RecyclerView,那么就需要在每个Adapter中都实现监听回调,无疑增加了代码的冗余度。
通过addOnItemTouchListener实现点击监听
RecyclerView虽然没有提供Item的监听方法,但还是提供了addOnItemTouchListener(OnItemTouchListenerlistener)监听Touch事件的方法,通过实现OnItemClickListener接口来实现监听。在实现过程中我们使用了手势监听类:GestureDetector(参考另一篇)。
OnItemTouchListener接口中一共有三个方法:
onInterceptTouchEvent
onTouchEvent
onRequestDisallowInterceptTouchEvent
学习过事件分发机制的同学,对这三个方法会比较熟悉,简单来说onInterceptTouchEvent对事件进行拦截,如果这个方法返回True,那么TouchEvent将会交给onTouchEvent处理(当然了你想在onInterceptTouchEvent中处理事件也没毛病),如果返回false,TouchEvent将传递到下层View处理。
显然我们需要拦截事件onInterceptTouchEvent返回true,然后处理事件
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
if(mGestureDetector.onTouchEvent(e)){
return true;
} else{
return false;
}
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept){
}
对于事件处理就需要GestureDetector出场了,GestureDetector是专门用于手势处理的类。
mGestureDetector = new GestureDetector(mContext, new GestureDetector.SimpleOnGestureListener(){
@Override
public void onLongPress(MotionEvente) {
if(listener != null){
View view = mRecyclerView.findChildViewUnder(e.getX(), e.getY());
listener.OnLongClick(view, mRecyclerView.getChildLayoutPosition(view));
}
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
if(listener != null){
View view = mRecyclerView.findChildViewUnder(e.getX(), e.getY());
listener.onClick(view, mRecyclerView.getChildLayoutPosition(view));
return true;
} else{
return false;
}
}
});
哦~ 对了,还需要在Activity中进行回调,实现方式同上面方法一,定义MyClickListener接口,添加set方法或者在构造方法中添加MyClickListener参数,在activity中实现回调。
vRecyclerView.addOnItemTouchListener(new MyOnItemTouchListener(LinearLayoutManagerActivity.this, vRecyclerView, new MyOnItemTouchListener.OnItemClickListener(){
@Override
public void onClick(Viewview, int position) {
Toast.makeText(LinearLayoutManagerActivity.this, "onClick: " + position, Toast.LENGTH_SHORT).show();
}
@Override
public void OnLongClick(Viewview, int position) {
Toast.makeText(LinearLayoutManagerActivity.this, "onLongClick: " + position, Toast.LENGTH_SHORT).show();
}
}));
对于复杂手势,比如滑动删除、滑动显示按钮了GestureDetector是干不了的,只能在onTouchEvent中自己写逻辑实现了。
通常实现监听的方法有两种:
通过在Adapter中设置监听回调来处理点击逻辑
通过设置RecyclerView.addOnItemTouchListener,并重写RecyclerView.OnItemTouchListener来实现
在Adapter中设置回调
实现逻辑跟我们平常设置监听回调的逻辑并无差别:
1.定义一个MyClickListener接口,并定义onClick()、onLongClick()等回调方法
2.在Adapter中定义一个MyClickListener对象,并提供设置方法setOnMyClickListener或者在构造方法中指定MyClickListener对象参数
3.在Adapter的onBindViewHolder中给View设置监听setOnclickListener和setOnLongClickLister等
4.Activity中进行回调,处理点击逻辑
代码:
public MyRecyclerViewAdapter(Context mContext, List<Integer> datas, MyOnClickListeneronClickListener){
this.mContext = mContext;
this.datas= datas;
this.onClickListener= onClickListener;
}
public void setOnclickListener(MyOnClickListener onClickListener){
this.onClickListener = onClickListener;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
((MyViewHolder)holder).mImageView.setImageResource(datas.get(position));
((MyViewHolder)holder).rootView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v){
if(onClickListener != null){
onClickListener.onClick(v, position);
}
}
});
((MyViewHolder)holder).rootView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if(onClickListener != null){
onClickListener.onLongClick(v, position);
}
return true;
}
});
}
/**
* 点击监听接口
*/
public interface MyOnClickListener{
void onClick(View view, int position);
void onLongClick(View view, int position);
}
在Activity中:
vRecyclerView.setAdapter(new MyRecyclerViewAdapter(this, datas, new MyOnClickListener() {
@Override
public void onClick(Viewview, int position) {
//点击
}
@Override
public void onLongClick(Viewview, int position) {
//长按
}
}));
这种实现方式的突出有点就是简单明了,易于实现。但是这种实现方式首先违背了但一直责原则,再者其与Adapter高度耦合的特点也决定了他的复用性比较低。比如:现在有多个不同的RecyclerView,那么就需要在每个Adapter中都实现监听回调,无疑增加了代码的冗余度。
通过addOnItemTouchListener实现点击监听
RecyclerView虽然没有提供Item的监听方法,但还是提供了addOnItemTouchListener(OnItemTouchListenerlistener)监听Touch事件的方法,通过实现OnItemClickListener接口来实现监听。在实现过程中我们使用了手势监听类:GestureDetector(参考另一篇)。
OnItemTouchListener接口中一共有三个方法:
onInterceptTouchEvent
onTouchEvent
onRequestDisallowInterceptTouchEvent
学习过事件分发机制的同学,对这三个方法会比较熟悉,简单来说onInterceptTouchEvent对事件进行拦截,如果这个方法返回True,那么TouchEvent将会交给onTouchEvent处理(当然了你想在onInterceptTouchEvent中处理事件也没毛病),如果返回false,TouchEvent将传递到下层View处理。
显然我们需要拦截事件onInterceptTouchEvent返回true,然后处理事件
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
if(mGestureDetector.onTouchEvent(e)){
return true;
} else{
return false;
}
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept){
}
对于事件处理就需要GestureDetector出场了,GestureDetector是专门用于手势处理的类。
mGestureDetector = new GestureDetector(mContext, new GestureDetector.SimpleOnGestureListener(){
@Override
public void onLongPress(MotionEvente) {
if(listener != null){
View view = mRecyclerView.findChildViewUnder(e.getX(), e.getY());
listener.OnLongClick(view, mRecyclerView.getChildLayoutPosition(view));
}
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
if(listener != null){
View view = mRecyclerView.findChildViewUnder(e.getX(), e.getY());
listener.onClick(view, mRecyclerView.getChildLayoutPosition(view));
return true;
} else{
return false;
}
}
});
哦~ 对了,还需要在Activity中进行回调,实现方式同上面方法一,定义MyClickListener接口,添加set方法或者在构造方法中添加MyClickListener参数,在activity中实现回调。
vRecyclerView.addOnItemTouchListener(new MyOnItemTouchListener(LinearLayoutManagerActivity.this, vRecyclerView, new MyOnItemTouchListener.OnItemClickListener(){
@Override
public void onClick(Viewview, int position) {
Toast.makeText(LinearLayoutManagerActivity.this, "onClick: " + position, Toast.LENGTH_SHORT).show();
}
@Override
public void OnLongClick(Viewview, int position) {
Toast.makeText(LinearLayoutManagerActivity.this, "onLongClick: " + position, Toast.LENGTH_SHORT).show();
}
}));
对于复杂手势,比如滑动删除、滑动显示按钮了GestureDetector是干不了的,只能在onTouchEvent中自己写逻辑实现了。
微测检测5.10
2023-05-10 广告
2023-05-10 广告
您好!建议咨 深圳市微测检测有限公司,已建立起十余个专业实验室,企业通过微测检测就可以获得一站式的测试与认 证解决方案;(EMC、RF、MFi、BQB、QI、USB、安全、锂电池、快充、汽车电子EMC、汽车手机互 联、语音通话质量),认证遇...
点击进入详情页
本回答由微测检测5.10提供
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询