RecyclerView点击事件处理

来源:互联网 发布:matlab编程题目 编辑:程序博客网 时间:2024/06/05 00:40

 RecyclerView本身并没有提供用于监听Item点击、长按等事件的方法(虽然有点蛋痛,但是应该也是有其原因的),需要我们自己实现来进行监听。

通常实现监听的方法有两种:

  • 通过在Adapter中设置监听回调来处理点击逻辑
  • 通过设置RecyclerView.addOnItemTouchListener,并重写RecyclerView.OnItemTouchListener来实现

 

Adapter中设置回调

实现逻辑跟我们平常设置监听回调的逻辑并无差别:

1.定义一个MyClickListener接口,并定义onClick()onLongClick()等回调方法

2.Adapter中定义一个MyClickListener对象,并提供设置方法setOnMyClickListener或者在构造方法中指定MyClickListener对象参数

3.AdapteronBindViewHolder中给View设置监听setOnclickListenersetOnLongClickLister

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(newView.OnClickListener() {

        @Override

        public voidonClick(View v){

            if(onClickListener!= null){

                onClickListener.onClick(v,position);

            }

        }

    });

 

    ((MyViewHolder)holder).rootView.setOnLongClickListener(newView.OnLongClickListener() {

        @Override

        public booleanonLongClick(View v) {

            if(onClickListener!= null){

                onClickListener.onLongClick(v,position);

            }

            return true;

        }

    });

}

 

/**

 * 点击监听接口

 */

public interface MyOnClickListener{

    voidonClick(View view, intposition);

    void onLongClick(View view, intposition);

}

 

Activity中:

vRecyclerView.setAdapter(newMyRecyclerViewAdapter(this,datas, newMyOnClickListener() {

    @Override

    public voidonClick(Viewview, intposition) {

       //点击

    }

 

    @Override

    public voidonLongClick(Viewview, intposition) {

       //长按

    }

}));

 

这种实现方式的突出有点就是简单明了,易于实现。但是这种实现方式首先违背了但一直责原则,再者其与Adapter高度耦合的特点也决定了他的复用性比较低。比如:现在有多个不同的RecyclerView,那么就需要在每个Adapter中都实现监听回调,无疑增加了代码的冗余度。

 

通过addOnItemTouchListener实现点击监听

RecyclerView虽然没有提供Item的监听方法,但还是提供了addOnItemTouchListener(OnItemTouchListenerlistener)监听Touch事件的方法,通过实现OnItemClickListener接口来实现监听。在实现过程中我们使用了手势监听类:GestureDetector(参考另一篇)。

OnItemTouchListener接口中一共有三个方法:

  • onInterceptTouchEvent
  • onTouchEvent
  • onRequestDisallowInterceptTouchEvent

学习过事件分发机制的同学,对这三个方法会比较熟悉,简单来说onInterceptTouchEvent对事件进行拦截,如果这个方法返回True,那么TouchEvent将会交给onTouchEvent处理(当然了你想在onInterceptTouchEvent中处理事件也没毛病),如果返回falseTouchEvent将传递到下层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(booleandisallowIntercept){

 

}

 

对于事件处理就需要GestureDetector出场了,GestureDetector是专门用于手势处理的类。

mGestureDetector =new GestureDetector(mContext, newGestureDetector.SimpleOnGestureListener(){

    @Override

    public voidonLongPress(MotionEvente) {

        if(listener!= null){

            View view = mRecyclerView.findChildViewUnder(e.getX(),e.getY());

            listener.OnLongClick(view,mRecyclerView.getChildLayoutPosition(view));

        }

    }

 

    @Override

    public booleanonSingleTapUp(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(newMyOnItemTouchListener(LinearLayoutManagerActivity.this,vRecyclerView, newMyOnItemTouchListener.OnItemClickListener(){

    @Override

    public voidonClick(Viewview, intposition) {

        Toast.makeText(LinearLayoutManagerActivity.this,"onClick: " + position,Toast.LENGTH_SHORT).show();

    }

 

    @Override

    public voidOnLongClick(Viewview, intposition) {

        Toast.makeText(LinearLayoutManagerActivity.this,"onLongClick: " + position,Toast.LENGTH_SHORT).show();

    }

}));

 

 

对于复杂手势,比如滑动删除、滑动显示按钮了GestureDetector是干不了的,只能在onTouchEvent中自己写逻辑实现了。

1 0