上篇文章我们讲解了RecyclerView的基本使用,本篇就让我们承接上篇文章讲下RecyclerView的进阶使用。
没看过上篇的朋友可以点击右边的传送门:《RecyclerView基本使用》
背景
RecyclerView有很多功能待发掘,刚好自己在工作过程中有遇到,因此抱着知识共享和互相学习的态度分享给大家。
本篇会讲3个RecyclerView的进阶使用。
01.点击监听
大家知道,我们以前使用ListView的时候,ListView有条目点击回调方法setOnItemClickListener。
但是用过RecyclerView的会发现,
竟然没有
竟然没有
竟然没有
是的,真的没有这个方法。
但是如果我真的要实现点击回调,怎么办呢?
这就是这里我们要说的啦。
我们可以通过在Adapter里面提供一个接口来达到类似的效果。
这里的Adapter为ItemClickRecyclerViewAdapter。
1.定义接口
public interface OnItemClickListener {
void onItemClick(View view, int position);
}
2.定义该接口的变量并提供set方法以便回调回去。
private OnItemClickListener mOnItemClickListener = null;
public void setOnItemClickListener(OnItemClickListener mOnItemClickListener) {
this.mOnItemClickListener = mOnItemClickListener;
}
3.在ItemClickRecyclerViewAdapter的onCreateViewHolder()方法里面对view设置点击监听。
@Override
public ItemClickRecyclerViewViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_main, parent, false);
view.setOnClickListener(this);
return new ItemClickRecyclerViewViewHolder(view);
}
NOTE:
为了把点击的位置回调回去,还需要在onBindViewHolder()方法做如下处理:
holder.itemView.setTag(position);
4.让ItemClickRecyclerViewAdapter实现监听并做回调处理。
@Override
public void onClick(View view) {
if (mOnItemClickListener != null) {
mOnItemClickListener.onItemClick(view, (int) view.getTag());
}
}
如此,点击监听就实现了。
02.互换位置
先上图:
好了,让我们看看如何实现上图的效果吧。
1.定义类DragItemTouchHelperCallback继承ItemTouchHelper.Callback。
2.定义一个接口用于上下拖动时交换位置。
public interface OnItemCallbackListener {
/**
* @param fromPosition 起始位置
* @param toPosition 移动的位置
*/
void onMove(int fromPosition, int toPosition);
}
3.DragItemTouchHelperCallback定义OnItemCallbackListener变量并作为参数通过构造函数传递进来。
private OnItemCallbackListener mOnItemCallbackListener;
public DragItemTouchHelperCallback(OnItemCallbackListener mOnItemCallbackListener) {
this.mOnItemCallbackListener = mOnItemCallbackListener;
}
4.修改getMovementFlags()方法设置为可上下拖拽。
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
//设置为可上下拖拽
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
return makeMovementFlags(dragFlags, 0);
}
5.修改onMove()方法提供回调。
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
/**
* 回调
*/
mOnItemCallbackListener.onMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return true;
}
6.让DragVerticalRecyclerViewAdapter实现我们的接口OnItemCallbackListener,并在onMove()方法中执行具体移动操作。
@Override
public void onMove(int fromPosition, int toPosition) {
/**
* 在这里进行给原数组数据的移动
* 第一个参数为数据源
*/
Collections.swap(itemList, fromPosition, toPosition);
/**
* 通知数据移动
*/
notifyItemMoved(fromPosition, toPosition);
}
7.将DragItemTouchHelperCallback与RecyclerView建立联系。
private ItemTouchHelper mItemTouchHelper;
//先实例化Callback
ItemTouchHelper.Callback callback = new DragItemTouchHelperCallback(mAdapter);
//用Callback构造ItemtouchHelper
mItemTouchHelper = new ItemTouchHelper(callback);
//调用ItemTouchHelper的attachToRecyclerView方法建立联系
mItemTouchHelper.attachToRecyclerView(mRecyclerView);
到这里,我们的互换位置就完成了。
当然这里默认是长按才可以拖动。
但是用过QQ的会发现直接点击就可以拖动了。
那么如何实现呢?让我们继续探索。
很简单,只需下面几步:
1.重写DragItemTouchHelperCallback中的isLongPressDragEnabled()方法。
@Override
public boolean isLongPressDragEnabled() {
return false;
}
2.在DragVerticalRecyclerViewActivity提供ItemTouchHelper的get()方法。
public ItemTouchHelper getItemTouchHelper() {
return mItemTouchHelper;
}
3.在onBindViewHolder()方法中设置触摸监听,然后调用startDrag()方法进行移动。
holder.itemView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
ItemTouchHelper itemTouchHelper = ((DragVerticalRecyclerViewActivity) (activity)).getItemTouchHelper();
if (itemTouchHelper != null) {
itemTouchHelper.startDrag(holder);
}
return true;
}
});
如此便实现了。
03.滑动删除
先上图
这里我们简单实现左滑右滑处理。
我们在原先的基础上做处理。
不过为了避免事件冲突,我们把点击上下拖拽改为长按上下拖拽。
然后说下左右滑动的处理:
1.在DragItemTouchHelperCallback的getMovementFlags()方法增加左右滑动。
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
//设置为可上下拖拽
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
//设置侧滑方向为左右
int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
return makeMovementFlags(dragFlags, swipeFlags);
}
2.OnItemCallbackListener接口增加左滑右滑回调。
public interface OnItemCallbackListener {
/**
* @param fromPosition 起始位置
* @param toPosition 移动的位置
*/
void onMove(int fromPosition, int toPosition);
//右滑
void onSwipeRight(int position);
//左滑
void onSwipeLift(int position);
}
3.在DragItemTouchHelperCallback的onSwiped()方法中调用。
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
if (direction == ItemTouchHelper.END) {
//Item滑动方向为右
mOnItemCallbackListener.onSwipeRight(viewHolder.getAdapterPosition());
} else if (direction == ItemTouchHelper.START) {
//Item滑动方向为左
mOnItemCallbackListener.onSwipeLift(viewHolder.getAdapterPosition());
}
}
4.在DragVerticalRecyclerViewAdapter实现左滑右滑接口方法。
@Override
public void onSwipeRight(int position) {
itemList.remove(position);
notifyItemRemoved(position);
Toast.makeText(activity, "swipe right", Toast.LENGTH_SHORT).show();
}
@Override
public void onSwipeLift(int position) {
itemList.remove(position);
notifyItemRemoved(position);
Toast.makeText(activity, "swipe left", Toast.LENGTH_SHORT).show();
}
这里简单做了移除item操作。如果要做一些其他的操作,就在这里的回调进行处理。
其中notifyItemRemoved(position);必写。
这样左滑右滑就实现了。是不是很简单。
代码点击源代码
昵称: 安卓小哥
邮箱: nesger.zhan@gmail.com
博客: https://nesger.github.io/
GitHub: https://github.com/nesger