RecyclerView.OnItemTouchListener
接口的监听抽象类,然后调用RecyclerView的addOnItemTouchListener
的方法给RecyclerView设置点击的监听。点击事件监听类的实现:
/**
* Created by on 2017/9/19.
*/
public abstract class OnRecyclerItemClickListener implements RecyclerView.OnItemTouchListener{
private RecyclerView mRecyclerView;
private GestureDetectorCompat mGestureDetectorCompat;
/**
* 在创建实例的时候,传进指定的RecyclerView实例
* 同时使用实现了GestureDetector.SimpleOnGestureListener接口的类实例来创建GestureDetector
* @param recyclerView
*/
public OnRecyclerItemClickListener(RecyclerView recyclerView) {
mRecyclerView = recyclerView;
mGestureDetectorCompat = new GestureDetectorCompat(mRecyclerView.getContext(),new ItemTouchHelperGestureListener());
}
/**
* 重写下面三个方法,让GestureDetector接收事件
* @param rv
* @param e
* @return
*/
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
mGestureDetectorCompat.onTouchEvent(e);
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
mGestureDetectorCompat.onTouchEvent(e);
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
/**
* 需要调用者,也就是RecyclerView实例实现的抽象方法
* @param viewHolder
*/
public abstract void onItemClick(RecyclerView.ViewHolder viewHolder);
public abstract void onLongClick(RecyclerView.ViewHolder viewHolder);
/**
* 实现一个GestureDetector,重写关于单点和长按方法
*/
private class ItemTouchHelperGestureListener extends GestureDetector.SimpleOnGestureListener{
@Override
public boolean onSingleTapUp(MotionEvent e) {
//通过点击事件的坐标,用findChileViewUnder找到被点击的view
View childViewUnder = mRecyclerView.findChildViewUnder(e.getX(),e.getY());
if (childViewUnder != null){
//通过被点击的view,用getChildViewHolder找到被点击的viewHolder
RecyclerView.ViewHolder childViewHolder = mRecyclerView.getChildViewHolder(childViewUnder);
onItemClick(childViewHolder); //回调
}
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View chileViewUnder = mRecyclerView.findChildViewUnder(e.getX(),e.getY());
if (chileViewUnder != null){
RecyclerView.ViewHolder childViewHolder = mRecyclerView.getChildViewHolder(chileViewUnder);
onLongClick(childViewHolder);
}
}
}
}
具体的使用:
public class Listener extends OnRecyclerItemClickListener{
public Listener(RecyclerView recyclerView){
super(recyclerView);
}
@Override
public void onItemClick(RecyclerView.ViewHolder viewHolder) {
//do someting;
}
@Override
public void onLongClick(RecyclerView.ViewHolder viewHolder) {
//do something;
}
}
Listener listener = new Listener(mRecyclerView);
mRecyclerView.addOnItemTouchListener(listener);
或者使用匿名内部类的方式:
mRecyclerView.addOnItemTouchListener(new OnRecyclerItemClickListener(mRecyclerView) {
@Override
public void onItemClick(RecyclerView.ViewHolder viewHolder) {
//do someting;
}
@Override
public void onLongClick(RecyclerView.ViewHolder viewHolder) {
//do something;
}
});
拖动可以使用ItemTouchHelper来实现,它的内部封装了很多的接口,包括拖动、侧滑、选中等等,我们只要将需要实现这些功能的view(不仅仅是RecyclerView)设置给它,然后自己实现接口里需要的逻辑就行了。
比如,实现回调接口类:
public class Call implements ItemTouchHelper.Callback{
//@Override 重写需要的方法;
...
}
然后用这个类的实例来创建ItemTouchHelper实例,再将RecyclerView或者其他的view设置给ItemTouchHelper实例
ItemTouchHelper helper = new ItemTouchHelper(new Call());
helper.attachToRecyclerView(mRecyclerView);
ItemTouchHelper.Callback的重写例子:
/**
* Created by on 2017/9/19.
*/
public class ItemTouchCallback extends ItemTouchHelper.Callback {
private NoteAdaper mNoteAdaper;
public ItemTouchCallback(){
super();
}
/**
* 通过使用RecyclerView的适配器来操作RecyclerView
* @param noteAdaper
*/
public ItemTouchCallback(NoteAdaper noteAdaper){
mNoteAdaper = noteAdaper;
}
/**
* 这个方法用于决定哪些方向的滑动是允许的,或者说是可以引起响应的
* @param recyclerView
* @param viewHolder
* @return int 返回一个整型,标志是否允许滑动
*/
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
//如果是线性的,设置拖拉方向为上和下,侧滑为左和右
if (recyclerView.getLayoutManager() instanceof LinearLayoutManager){
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
return makeMovementFlags(dragFlags,swipeFlags);
}else{ //如果是表格性的,设置上下左右四个方向
if (recyclerView.getLayoutManager()instanceof GridLayoutManager){
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN
|ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
int swipeFlags = 0; //0代表不滑动
return makeMovementFlags(dragFlags,swipeFlags);
}
}
return 0;
}
/**
* 这个方法响应拖动事件
* @param recyclerView
* @param viewHolder 被拖动的viewHolder
* @param target 位置被代替的viewHolder
* @return
*/
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
int fromPostion = viewHolder.getAdapterPosition();
int toPosition = target.getAdapterPosition();
//如果子项是向下托拉,从拖拉位置开始的地方到目标位置的前一个位置,全部子项向后一个子项交换数据
if (fromPostion < toPosition){
for (int i = fromPostion; i < toPosition; i ++){
Collections.swap(mNoteAdaper.getDataList(),i,i + 1);
}
}else { //如果子项是向上拖拉,从拖拉位置开始到目标位置的下一个位置,全部子项向前一个子项交换数据
for (int i = fromPostion; i > toPosition; i--){
Collections.swap(mNoteAdaper.getDataList(),i,i - 1);
}
}
//上一步交换完数据,这一步交换视图
mNoteAdaper.notifyItemMoved(fromPostion,toPosition);
return true;
}
/**
* 这个方法响应侧滑
* @param viewHolder 被滑动的子项
* @param direction 滑动方向,可以根据不同的方向做不同的事情
*/
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
int adapterPosition = viewHolder.getAdapterPosition(); //获得被侧滑的子项位置
mNoteAdaper.notifyItemRemoved(adapterPosition); //视图清除
mNoteAdaper.getDataList().remove(adapterPosition); //数据清除
}
/**
* 响应选中
* @param viewHolder 被选中的子项
* @param actionState 子项的选中状态,可以根据子项的选中状态做不同的处理
*/
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE){ //ItemTouchHelper.ACTION_STATE_IDLE 空闲状态
viewHolder.itemView.setBackground(MyApplication.getContext().getDrawable(R.drawable.gray));
}
super.onSelectedChanged(viewHolder, actionState);
}
/**
* 这个方法用于当拖动、侧滑、选中等等动作消失后,需要做的处理
* @param recyclerView
* @param viewHolder 被操作的子项
*/
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
viewHolder.itemView.setBackground(MyApplication.getContext().getDrawable(R.drawable.white));
}
}
使用例子:
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchCallback(mNoteAdaper));
itemTouchHelper.attachToRecyclerView(mRecyclerView);
方式1:
创建一个drawable对象,然后在子项布局的底部加一个ImageView,然后设置这个drawable对象为背景,drawable对象:
"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android">
"@color/gray"/>
"1px"/>
方式2:
使用RecyclerView的addItemDecoration方法:
mRecyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL));