RecyclerView的点击事件

xiaoxiao2021-02-28  66

方法一:利用View.onClickListener及onLongClickListener

利用了java回调机制,这里我们依赖于子Item View的onClickListener及onLongClickListener。 首先对MyAdapter.java代码做出如下修改: ①新建两个内部接口: public interface OnItemClickListener{ void onItemClick(View view,int position); } public interface OnItemLongClickListener{ void onItemLongClick(View view,int position); } ②新建两个私有变量用于保存用户设置的监听器及其set方法: private OnItemClickListener mOnItemClickListener; private OnItemLongClickListener mOnItemLongClickListener; public void setOnItemClickListener(OnItemClickListener mOnItemClickListener){ this.mOnItemClickListener = mOnItemClickListener; } public void setOnItemLongClickListener(OnItemLongClickListener mOnItemLongClickListener) { this.mOnItemLongClickListener = mOnItemLongClickListener; } ③在onBindViewHolder方法内,实现回调: 这里监听写在了里面 能够 holder.getLayoutPosition()拿到位置信息,如果将监听事件写在外面的话,我们可以通过view.settag() 和view.gettag()来获取位置信息 @Override public void onBindViewHolder(final ViewHolder holder, int position) { holder.mTextView.setText(mDataSet.get(position)); //判断是否设置了监听器 if(mOnItemClickListener != null){ //为ItemView设置监听器 holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int position = holder.getLayoutPosition(); // 1 mOnItemClickListener.onItemClick(holder.itemView,position); // 2 } }); } if(mOnItemLongClickListener != null){ holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { int position = holder.getLayoutPosition(); mOnItemLongClickListener.onItemLongClick(holder.itemView,position); //返回true 表示消耗了事件 事件不会继续传递 return true; } }); } } 可以看到,这里实际上用到了子Item View的onClickListener和onLongClickListener这两个监听器,如果当前子item view被点击了, 会触发点击事件进行回调,然后在①处获取当前点击位置的position值,接着在②号代码处进行再次回调,而这一次的回调是我们自己手动添加的, 需要实现上面所述的接口。 修改完MyAdapter.java后,我们接着在MainActivity.java中设置监听器,采用匿名内部类的形式实现了onItemClickListener、onItemLongClickListener 接口,这种写法与一般的设置监听器的流程相同: mAdapter = new MyAdapter(mData); mAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() { @Override public void onItemClick(View view, int position) { Toast.makeText(MainActivity.this, "click " + mData.get(position), Toast.LENGTH_SHORT).show(); } }); mAdapter.setOnItemLongClickListener(new MyAdapter.OnItemLongClickListener() { @Override public void onItemLongClick(View view, int position) { Toast.makeText(MainActivity.this,"long click "+mData.get(position),Toast.LENGTH_SHORT).show(); } }); mRecyclerView.setAdapter(mAdapter);

利用RecyclerView.OnItemTouchListener

安卓SDK为我们提供了一个手势检测类:GestureDetector来处理各种不同的手势,那么我们完全可以利用GestureDetector来 进行单击、长按的判断 package com.example.administrator.mystudydemo.utils; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; /** * Created by Administrator on 2017/5/5. */ public class RecyclerViewClickListener implements RecyclerView.OnItemTouchListener { private GestureDetector mGestureDetector; private OnItemClickListener mListener; //内部接口,定义点击方法以及长按方法 public interface OnItemClickListener { void onItemClick(View view, int position); void onItemLongClick(View view, int position); } public RecyclerViewClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) { mListener = listener; mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { //这里选择SimpleOnGestureListener实现类,可以根据需要选择重写的方法 //单击事件 @Override public boolean onSingleTapUp(MotionEvent e) { View childView = recyclerView.findChildViewUnder(e.getX(), e.getY()); if (childView != null && mListener != null) { mListener.onItemClick(childView, recyclerView.getChildLayoutPosition(childView)); return true; } return false; } //长按事件 @Override public void onLongPress(MotionEvent e) { View childView = recyclerView.findChildViewUnder(e.getX(), e.getY()); if (childView != null && mListener != null) { mListener.onItemLongClick(childView, recyclerView.getChildLayoutPosition(childView)); } } }); } @Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { //把事件交给GestureDetector处理 if (mGestureDetector.onTouchEvent(e)) { return true; } else return false; } @Override public void onTouchEvent(RecyclerView rv, MotionEvent e) { } @Override public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { } }
应用 recyclerView= (RecyclerView) findViewById(R.id.rv_click); ClickAdapter adapter=new ClickAdapter(ClickActivity.this); recyclerView.addOnItemTouchListener(new RecyclerViewClickListener(ClickActivity.this, recyclerView, new RecyclerViewClickListener.OnItemClickListener() { @Override public void onItemClick(View view, int position) { Toast.makeText(ClickActivity.this,"点击的是"+position,Toast.LENGTH_SHORT).show(); } @Override public void onItemLongClick(View view, int position) { Toast.makeText(ClickActivity.this,"长按点击的是"+position,Toast.LENGTH_SHORT).show(); } })); recyclerView.setLayoutManager(new LinearLayoutManager(ClickActivity.this)); recyclerView.setAdapter(adapter); }

那么方法一和方法二有何区别

首先,方法一我们是直接在MyAdapter数据适配器中,为itemview设置了内置监听器,再通过这个监听器实现我们的回调方法,相当于回调了两次, 同时这个方法与MyAdapter的耦合度比较高,也违反了单一职责原则,当然其简易性也是突出的优点。而方法二,我们利用了onTouchListener接口对 事件进行了拦截,在拦截中处理我们的点击事件,实现了与适配器的解耦,但是复杂程度会比方法一大。总地来说,如果RecyclerView需要处理的点击 事件逻辑很简单,那么可以使用方法一;如果需要处理比较复杂的点击事件,比如说,双击、长按等点击事件,则需要使用方法二去实现各种复杂的逻辑。
转载请注明原文地址: https://www.6miu.com/read-31373.html

最新回复(0)