实现这么个功能我们不需要再去继承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 @Override29 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 @Override51 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 @Override63 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 @Override76 public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {77 // 正常默认状态下背景恢复默认78 viewHolder.itemView.setBackgroundColor(0);79 ViewCompat.setTranslationX(viewHolder.itemView,0);80 }81 });82 // 这个就不多解释了,就这么attach83 itemTouchHelper.attachToRecyclerView(mRecyclerView);
2.完整代码:
1 public class DragItemAnimatorActivity extends AppCompatActivity { 2 private WrapRecyclerView mRecyclerView; 3 private HomeAdapter mAdapter; 4 5 private ListmItems = new ArrayList (); 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 @Override102 public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {103 // 正常默认状态下背景恢复默认104 viewHolder.itemView.setBackgroundColor(0);105 ViewCompat.setTranslationX(viewHolder.itemView,0);106 }107 });108 // 这个就不多解释了,就这么attach109 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 @Override127 public boolean onCreateOptionsMenu(Menu menu) {128 getMenuInflater().inflate(R.menu.main, menu);129 return super.onCreateOptionsMenu(menu);130 }131 132 @Override133 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 {146 147 148 public HomeAdapter(Context context, List data) {149 super(context, data, R.layout.item_drag_sort_delete);150 }151 152 @Override153 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 }
参考: