Android——RecyclerView——使用ItemDragHelper来实现酷炫拖拽效果
来源:互联网 发布:淘宝卖家评价举报功能 编辑:程序博客网 时间:2024/06/07 00:54
参考资料
参考资料1
参考资料2
参考资料3【推荐】
背景介绍
列表控件可以说是我们绝大部分App中都会使用的,为了提升交互乐趣,我们经常需要在列表中加入拖拽、滑动等操作,本篇我将介绍使用ItemDragHelper这个官方提供的交互帮助类来帮助RecyclerView实现这些复杂的交互。
走进ItemTouchHelper
要使用这个类,最关键的步骤是传给它一个ItemTouchHelper.Callback,其它的我们可以不用管。既然它是一个Callback,那么我们可以大概猜到,我们自然就是在它的一些回调函数里做操作了。下面我们就来看看我们需要在哪些回调函数里做操作。
先上个效果图:
public class CustomItemTouchHelperCallback extends ItemTouchHelper.Callback { private OnItemTouchCallbackListener onItemTouchCallbackListener; private boolean canDrag = true; private boolean canSwipe = true; public CustomItemTouchHelperCallback(OnItemTouchCallbackListener onItemTouchCallbackListener) { this.onItemTouchCallbackListener = onItemTouchCallbackListener; } @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); int dragFlags = 0; int swipeFlags = 0; if (layoutManager instanceof GridLayoutManager) { // 如果是Grid布局,则不能滑动,只能上下左右拖动 dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; swipeFlags = 0; } else if (layoutManager instanceof LinearLayoutManager) { // 如果是纵向Linear布局,则能上下拖动,左右滑动 if (((LinearLayoutManager) layoutManager).getOrientation() == LinearLayoutManager.VERTICAL) { dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; swipeFlags = ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT; } else { // 如果是横向Linear布局,则能左右拖动,上下滑动 swipeFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; dragFlags = ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT; } } return makeMovementFlags(dragFlags, swipeFlags); //该方法指定可进行的操作 } /** * 拖动时回调,在这里处理拖动事件 * * @param viewHolder 被拖动的view * @param target 目标位置的view */ @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { //这里我们直接将参数传递到回调接口方法中,提高复用性 return onItemTouchCallbackListener.onMove(recyclerView, viewHolder, target); } /** * 滑动时回调 * * @param direction 回调方向 */ @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { onItemTouchCallbackListener.onSwiped(viewHolder, direction); } /** * 在这个回调中,如果返回true,表示可以触发长按拖动事件,false则表示不能 */ @Override public boolean isLongPressDragEnabled() { return canDrag; } /** * 在这个回调中,如果返回true,表示可以触发滑动事件,false表示不能 */ @Override public boolean isItemViewSwipeEnabled() { return canSwipe; } public void setCanDrag(boolean canDrag) { this.canDrag = canDrag; } public void setCanSwipe(boolean canSwipe) { this.canSwipe = canSwipe; }}
下面我们看看怎么来使用这个我们自定义的Callback。
public class DraggerRecyclerViewActivity extends BaseActivity { @BindView(R.id.rv_dragger_list) RecyclerView draggerList; private List<String> datas = new ArrayList<>(); private TextTestAdapter adapter; private CustomItemTouchHelper itemTouchHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_dragger_recycler_view); ButterKnife.bind(this); initData(); initView(); addListener(); } @Override protected void initData() { for (int i = 0; i < 100; i++) { datas.add("我是Item" + i); } } @Override protected void initView() { draggerList.setItemAnimator(new DefaultItemAnimator()); draggerList.addItemDecoration(new RecyclerView.ItemDecoration() { @Override public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) { if (itemPosition != parent.getChildCount() - 1) { outRect.bottom = (int) DisplayUtils.dipToPx(0.5f); } } }); draggerList.setLayoutManager(new LinearLayoutManager(this)); adapter = new TextTestAdapter(this, datas); //创建ItemTouchHelper itemTouchHelper = new CustomItemTouchHelper(new OnItemTouchCallbackListener() { @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { if (datas == null) { return false; } //处理拖动排序 //使用Collection对数组进行重排序,目的是把我们拖动的Item换到下一个目标Item的位置 Collections.swap(datas, viewHolder.getAdapterPosition(), target.getAdapterPosition()); //通知Adapter它的Item发生了移动 adapter.notifyItemMoved(viewHolder.getAdapterPosition(), target.getAdapterPosition()); return true; } @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { if (datas == null) { return; } //处理滑动删除 //直接从数据中删除该Item的数据 datas.remove(viewHolder.getAdapterPosition()); //通知Adapter有Item被移除了 adapter.notifyItemRemoved(viewHolder.getAdapterPosition()); } }); //并绑定RecyclerView itemTouchHelper.attachToRecyclerView(draggerList); draggerList.setAdapter(adapter); } @Override protected void addListener() { }}
下面是ItemTouchHelper。
public class CustomItemTouchHelper extends ItemTouchHelper { public CustomItemTouchHelper(OnItemTouchCallbackListener onItemTouchCallbackListener) { //直接把回调交给父类处理就好 super(new CustomItemTouchHelperCallback(onItemTouchCallbackListener)); }}
很简单是不是?把它自定义出来其实就是为了防止后期还要添加别的操作,如果不需要,可以直接用API中的ItemTouchHelper。
总结
归根结底,使用ItemTouchHelper来实现RecyclerView的拖拽、滑动操作,最主要的还是重写ItemTouchHelper.Callback,在这个回调中,比较重要的方法是以下几个:
- getMovementFlags(): 这个方法中需要返回可进行的操作Flags,这些Flags需要调用下面的方法合成;
- makeMovementFlags():这个方法将drag和move操作的Flags合成,作为getMovementFlags中的返回项;
- onMove():发生拖动时调用;
- onSwiped():发生滑动时调用;
- isLongPressDragEnabled():是否能触发长按拖动;
- isItemViewSwipeEnabled():是否能触发滑动;
探讨
最近看到一个观点,说美国犯罪率的下降应该大部分归功于堕胎合法化的政策,而不是别的因素。因为堕胎使很多底层人民,他们意外怀孕,却无力好好抚养孩子,提供良好的生存环境给他们,这些孩子在未来是最有可能从事犯罪的。而堕胎的合法化使这些孩子一部分未能来到这个世界上,所以从根源上导致了犯罪率的下降。
这事儿,你怎么看?
- Android——RecyclerView——使用ItemDragHelper来实现酷炫拖拽效果
- Android开发之实现水平滚动效果—RecyclerView
- Android开发——使用RadioGroup及Fragment来实现底部Tab效果
- Android开发技巧——使用RecyclerView实现分组列表
- RecyclerView的简单使用(一)———— 实现各种布局效果
- Android基础控件——RecyclerView实现拖拽排序侧滑删除效果
- Android基础控件——RecyclerView实现混排效果,仿网易云音乐
- 应用RecyclerView实现Gallery相册效果——注意引入recyclerview-v7的版本
- android 5.x—RecyclerView使用介绍
- Android控件—RecyclerView
- Android—RecyclerView
- Android RecyclerView实现listview效果
- Android 使用shape来实现界面效果
- Android时间轴(Timeline)效果的实现(使用RecyclerView)
- Android 中使用 RecyclerView + SnapHelper 实现类似 ViewPager 效果
- Android 中使用 RecyclerView + SnapHelper 实现类似 ViewPager 效果
- Android中使用RecyclerView + SnapHelper实现类似ViewPager效果
- Android使用Recyclerview实现图片水平自动循环滚动效果
- Mysql必知必会(笔记)【SQL游标】
- spring-06-如何向响应JSP传值
- OpenCV Tutorial: 分水嶺算法(watershed)
- Xcode 8如何继续使用插件
- php中使用python生成excel报表
- Android——RecyclerView——使用ItemDragHelper来实现酷炫拖拽效果
- Android Material Design之Toolbar与Palette实践
- 彻底卸载ORACLE数据库
- shiro初步学习
- 建行E商贸通支付开发系列之三(2、密钥生成与交换)
- 【css3】鼠标悬停图片旋转效果
- 关于C51编译器的声明标识符
- OpenCV Tutorial: 影像分割(grabCut)
- 一张关于docker版本的图