实现这么个功能我们不需要再去继承RecyclerView,只需要去了解ItemTouchHelper这个类即可,接下来我们就去看看都有些什么
ItemTouchHelper.Callback 默认需要实现三个方法:
getMovementFlags() 获取Touch的响应方向,包含两个 1.拖动dragFlags 2.侧滑删除swipeFlags,都可以是上下左右,上面事例没有处理拖动所以传的是0,侧滑给的是ItemTouchHelper.LEFT,所以待会效果是向左滑动删除;
onMove() 拖动的时候会不断的回调这个方法,拖动的时候肯定需要不断的更新列表数据,达到一边拖动列表不断更新当前数据;
onSwiped() 侧滑删除之后的回调方法。
1.关键代码:
1 // 实现左边侧滑删除 和 拖动排序 2 ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() { 3 @Override 4 public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { 5 // 获取触摸响应的方向 包含两个 1.拖动dragFlags 2.侧滑删除swipeFlags 6 // 代表只能是向左侧滑删除,当前可以是这样ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT 7 int swipeFlags = ItemTouchHelper.LEFT; 8 9 10 // 拖动 11 int dragFlags = 0; 12 if (recyclerView.getLayoutManager() instanceof GridLayoutManager) { 13 // GridView 样式四个方向都可以 14 dragFlags = ItemTouchHelper.UP | ItemTouchHelper.LEFT | 15 ItemTouchHelper.DOWN | ItemTouchHelper.RIGHT; 16 } else { 17 // ListView 样式不支持左右 18 dragFlags = ItemTouchHelper.UP | 19 ItemTouchHelper.DOWN; 20 } 21 22 return makeMovementFlags(dragFlags, swipeFlags); 23 } 24 25 /** 26 * 拖动的时候不断的回调方法 27 */ 28 @Override 29 public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { 30 // 获取原来的位置 31 int fromPosition = viewHolder.getAdapterPosition(); 32 // 得到目标的位置 33 int targetPosition = target.getAdapterPosition(); 34 if (fromPosition > targetPosition) { 35 for (int i = fromPosition; i < targetPosition; i++) { 36 Collections.swap(mItems, i, i + 1);// 改变实际的数据集 37 } 38 } else { 39 for (int i = fromPosition; i > targetPosition; i--) { 40 Collections.swap(mItems, i, i - 1);// 改变实际的数据集 41 } 42 } 43 mAdapter.notifyItemMoved(fromPosition, targetPosition); 44 return true; 45 } 46 47 /** 48 * 侧滑删除后会回调的方法 49 */ 50 @Override 51 public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { 52 // 获取当前删除的位置 53 int position = viewHolder.getAdapterPosition(); 54 mItems.remove(position); 55 // adapter 更新notify当前位置删除 56 mAdapter.notifyItemRemoved(position); 57 } 58 59 /** 60 * 拖动选择状态改变回调 61 */ 62 @Override 63 public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { 64 if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) { 65 // ItemTouchHelper.ACTION_STATE_IDLE 看看源码解释就能理解了 66 // 侧滑或者拖动的时候背景设置为灰色 67 viewHolder.itemView.setBackgroundColor(Color.GRAY); 68 } 69 } 70 71 72 /** 73 * 回到正常状态的时候回调 74 */ 75 @Override 76 public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { 77 // 正常默认状态下背景恢复默认 78 viewHolder.itemView.setBackgroundColor(0); 79 ViewCompat.setTranslationX(viewHolder.itemView,0); 80 } 81 }); 82 // 这个就不多解释了,就这么attach 83 itemTouchHelper.attachToRecyclerView(mRecyclerView);
2.完整代码:
1 public class DragItemAnimatorActivity extends AppCompatActivity { 2 private WrapRecyclerView mRecyclerView; 3 private HomeAdapter mAdapter; 4 5 private List<ItemBean> mItems = new ArrayList<ItemBean>(); 6 7 @Override 8 protected void onCreate(Bundle savedInstanceState) { 9 super.onCreate(savedInstanceState); 10 setContentView(R.layout.activity_recycler_view); 11 12 initData(); 13 14 mRecyclerView = (WrapRecyclerView) findViewById(R.id.recycler_view); 15 16 17 mAdapter = new HomeAdapter(this, mItems); 18 19 mRecyclerView.setLayoutManager(new GridLayoutManager(this, 4)); 20 mRecyclerView.setAdapter(mAdapter); 21 22 mRecyclerView.addItemDecoration(new DividerGridItemDecoration(this)); 23 24 final DefaultItemAnimator itemAnimator = new DefaultItemAnimator(); 25 mRecyclerView.setItemAnimator(itemAnimator); 26 27 // 实现左边侧滑删除 和 拖动排序 28 ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() { 29 @Override 30 public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { 31 // 获取触摸响应的方向 包含两个 1.拖动dragFlags 2.侧滑删除swipeFlags 32 // 代表只能是向左侧滑删除,当前可以是这样ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT 33 int swipeFlags = ItemTouchHelper.LEFT; 34 35 36 // 拖动 37 int dragFlags = 0; 38 if (recyclerView.getLayoutManager() instanceof GridLayoutManager) { 39 // GridView 样式四个方向都可以 40 dragFlags = ItemTouchHelper.UP | ItemTouchHelper.LEFT | 41 ItemTouchHelper.DOWN | ItemTouchHelper.RIGHT; 42 } else { 43 // ListView 样式不支持左右 44 dragFlags = ItemTouchHelper.UP | 45 ItemTouchHelper.DOWN; 46 } 47 48 return makeMovementFlags(dragFlags, swipeFlags); 49 } 50 51 /** 52 * 拖动的时候不断的回调方法 53 */ 54 @Override 55 public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { 56 // 获取原来的位置 57 int fromPosition = viewHolder.getAdapterPosition(); 58 // 得到目标的位置 59 int targetPosition = target.getAdapterPosition(); 60 if (fromPosition > targetPosition) { 61 for (int i = fromPosition; i < targetPosition; i++) { 62 Collections.swap(mItems, i, i + 1);// 改变实际的数据集 63 } 64 } else { 65 for (int i = fromPosition; i > targetPosition; i--) { 66 Collections.swap(mItems, i, i - 1);// 改变实际的数据集 67 } 68 } 69 mAdapter.notifyItemMoved(fromPosition, targetPosition); 70 return true; 71 } 72 73 /** 74 * 侧滑删除后会回调的方法 75 */ 76 @Override 77 public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { 78 // 获取当前删除的位置 79 int position = viewHolder.getAdapterPosition(); 80 mItems.remove(position); 81 // adapter 更新notify当前位置删除 82 mAdapter.notifyItemRemoved(position); 83 } 84 85 /** 86 * 拖动选择状态改变回调 87 */ 88 @Override 89 public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { 90 if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) { 91 // ItemTouchHelper.ACTION_STATE_IDLE 看看源码解释就能理解了 92 // 侧滑或者拖动的时候背景设置为灰色 93 viewHolder.itemView.setBackgroundColor(Color.GRAY); 94 } 95 } 96 97 98 /** 99 * 回到正常状态的时候回调 100 */ 101 @Override 102 public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { 103 // 正常默认状态下背景恢复默认 104 viewHolder.itemView.setBackgroundColor(0); 105 ViewCompat.setTranslationX(viewHolder.itemView,0); 106 } 107 }); 108 // 这个就不多解释了,就这么attach 109 itemTouchHelper.attachToRecyclerView(mRecyclerView); 110 } 111 112 protected void initData() { 113 for (int i = 0; i < 10; i++) { 114 mItems.add(new ItemBean(i * 8 + 0, "收款", R.drawable.takeout_ic_category_brand)); 115 mItems.add(new ItemBean(i * 8 + 1, "转账", R.drawable.takeout_ic_category_flower)); 116 mItems.add(new ItemBean(i * 8 + 2, "余额宝", R.drawable.takeout_ic_category_fruit)); 117 mItems.add(new ItemBean(i * 8 + 3, "手机充值", R.drawable.takeout_ic_category_medicine)); 118 mItems.add(new ItemBean(i * 8 + 4, "医疗", R.drawable.takeout_ic_category_motorcycle)); 119 mItems.add(new ItemBean(i * 8 + 5, "彩票", R.drawable.takeout_ic_category_public)); 120 mItems.add(new ItemBean(i * 8 + 6, "电影", R.drawable.takeout_ic_category_store)); 121 mItems.add(new ItemBean(i * 8 + 7, "游戏", R.drawable.takeout_ic_category_sweet)); 122 } 123 mItems.add(new ItemBean(mItems.size(), "更多", R.drawable.takeout_ic_more)); 124 } 125 126 @Override 127 public boolean onCreateOptionsMenu(Menu menu) { 128 getMenuInflater().inflate(R.menu.main, menu); 129 return super.onCreateOptionsMenu(menu); 130 } 131 132 @Override 133 public boolean onOptionsItemSelected(MenuItem item) { 134 switch (item.getItemId()) { 135 case R.id.id_action_gridview: 136 mRecyclerView.setLayoutManager(new GridLayoutManager(this, 4)); 137 break; 138 case R.id.id_action_listview: 139 mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); 140 break; 141 } 142 return true; 143 } 144 145 class HomeAdapter extends CommonRecyclerAdapter<ItemBean> { 146 147 148 public HomeAdapter(Context context, List<ItemBean> data) { 149 super(context, data, R.layout.item_drag_sort_delete); 150 } 151 152 @Override 153 public void convert(ViewHolder holder, ItemBean item) { 154 holder.setText(R.id.item_text, item.text); 155 holder.setImageResource(R.id.item_img, item.icon); 156 } 157 } 158 159 public class ItemBean { 160 public int id; 161 public String text; 162 public int icon; 163 164 public ItemBean(int id, String text, int icon) { 165 this.id = id; 166 this.text = text; 167 this.icon = icon; 168 } 169 } 170 }