RecyclerView实现长按、拖拉、滑动、选中、分割线
来源:互联网 发布:mac 退出全屏快捷键 编辑:程序博客网 时间:2024/06/07 17:53
- 长按
- 拖动侧滑选中
- 下滑线
- 一个可以参考一下的便签app 还没完善全部功能
长按
- RecyclerView没有提供监听点击事件的接口,没有mRecyclerView.setOn…,但是可以实现一个实现了
RecyclerView.OnItemTouchListener
接口的监听抽象类,然后调用RecyclerView的addOnItemTouchListener
的方法给RecyclerView设置点击的监听。 - 默认的时候,view的事件序列是会被TouchEvent截获的,而TouchEvent不提供双击和长按,想让view具备响应双击和长按,需要创建一个实现GestureDetector的接口的类,然后在TouchEvent里让这个类的实例来接收事件。所以,RecyclerView也一样,它需要在内部给自己创建一个这样的类,然后在自己的TouchEvent方法里接收事件序列。
- 无论是给RecyclerView设置点击监听,还是为点击监听设置GestureDetecor,还是为GestureDetector设置回调,都只是让它们具备了基本的能力,具体的逻辑能力需要自己写。
总的思路就是:
1.为RecyclerView添加OnItemTouchListener,让RecyclerView具备事件分发;
2.为ReyeclerView的事件分发设置GestureDetector,让RecyclerView可以响应双击或者长按等;
3.在GestureDetector的具体实现里,结合RecyclerView的2个方法判断出具体的子项;
4.判断出具体的子项之后,用回调函数交给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对象:
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="@color/gray"/> <size android:height="1px"/></shape>
方式2:
使用RecyclerView的addItemDecoration方法:
mRecyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL));
一个可以参考一下的便签app (还没完善全部功能)
阅读全文
1 0
- RecyclerView实现长按、拖拉、滑动、选中、分割线
- RecyclerView 梳理:点击&长按事件、分割线、拖曳排序、滑动删除
- RecyclerView 梳理:点击&长按事件、分割线、拖曳排序、滑动删除
- RecyclerView(实现分割线)
- RecyclerView自定义分割线实现
- Android初识RecyclerView 添加分割线、单击事件、长按事件
- android recyclerview的使用,添加分割线,点击,长按事件
- 实现 Recyclerview 的分割线 RecyclerDecoration
- RecyclerView实现列表Item长按移动、左右滑动删除
- RecyclerView分割线
- RecyclerView分割线详解
- RecyclerView分割线
- RecyclerView虚线分割线
- Android Recyclerview分割线
- RecyclerView万能分割线
- recyclerview分割线 -总结
- RecyclerView分割线
- RecyclerView分割线
- 重绘Winform窗体
- POJ 3295.Tautology
- LeetCode 525. Contiguous Array
- 如何进行Cause GC且解决Heap updates are NOT ENABLED for this client
- @SuppressWarnings可以抑制的警告类型
- RecyclerView实现长按、拖拉、滑动、选中、分割线
- MySQL数据库事务隔离级别
- 2017-9-17pat甲级 A
- 异常类的toString()、getMessage()和printStackTrace()方法
- 今日头条项目xml
- elasticsearch在centos上的学习过程2
- 数组的输出(传统方式与非传统方式)
- LSR报文格式
- Effective Java中文第三章第10节(个人渣翻)