RecyclerView ItemTouchHelper 实现上下拖拽排序 滑动删除
<Excerpt in index | 首页摘要>
RecyclerView ItemTouchHelper 实现上下拖拽排序 滑动删除
<The rest of contents | 余下全文>
概述
不得不说RecyclerView的强大简直无可匹敌。
今天学习到他有一个帮助类,叫做ItemTouchHelper
看名字就可以得知它是帮助我们在item的操作上面提供给我们一些帮助的效果。
item操作主要是两种,一种是拖拽:drag,一种是滑动:swipe
效果图
让我们先来看看效果图:
UI代码
通过实践发现这个帮助类相当的强大,而且使用起来也十分的简单与方便。
具体看代码
界面代码:
1 2 3 4 5 6 7 8 9 10 11
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">
<android.support.v7.widget.RecyclerView android:id="@+id/mRecyclerView" android:layout_width="match_parent" android:layout_height="match_parent" />
</LinearLayout>
|
itemxml代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="60dp" android:background="#fff" android:orientation="vertical">
<ImageView android:id="@+id/image" android:layout_width="48dp" android:layout_height="48dp" android:layout_gravity="center_vertical" android:layout_marginLeft="12dp" android:src="@mipmap/ic_launcher" />
<TextView android:id="@+id/nick" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="68dp" android:layout_marginTop="6dp" android:text="nick" android:textSize="16sp" />
<TextView android:id="@+id/desc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_marginBottom="8dp" android:layout_marginLeft="68dp" android:text="desc" android:textSize="15sp" />
<TextView android:id="@+id/time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" android:layout_marginRight="8dp" android:layout_marginTop="6dp" android:text="09:55:31" /> </FrameLayout>
|
这个都十分的简单
看看初始化代码!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initData(); mRecyclerView = (WrapRecyclerView) findViewById(R.id.mRecyclerView); mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); mRecyclerView.setAdapter(new Adapter()); mHelper = new ItemTouchHelper(new MyHelperCall((ItemMoveListener) mRecyclerView.getAdapter())); mHelper.attachToRecyclerView(mRecyclerView); }
private void initData() { mDatas = new ArrayList<>(); for (int i = 0; i < 50; i++) { mDatas.add(new Bean("nick" + i, "desc" + i)); } }
|
先看下ItemMoveListener接口:
1 2 3 4 5 6
| public interface ItemMoveListener { void onMove(int srcPos, int targetPos);
void onRemove(int pos); }
|
为了模拟数据我们还有一个pojo类
1 2 3 4 5 6 7 8 9
| private class Bean { String nick; String desc;
public Bean(String nick, String desc) { this.nick = nick; this.desc = desc; } }
|
让我们看下viewHolder
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Holder extends RecyclerView.ViewHolder {
ImageView image; TextView nick; TextView desc;
public Holder(View itemView) { super(itemView); image = (ImageView) itemView.findViewById(R.id.image); nick = (TextView) itemView.findViewById(R.id.nick); desc = (TextView) itemView.findViewById(R.id.desc); } }
|
具体逻辑代码
先看一下adapter的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| class Adapter extends RecyclerView.Adapter<Holder> implements ItemMoveListener {
@Override public Holder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(MainActivity.this) .inflate(R.layout.item, parent, false); return new Holder(view); }
@Override public void onBindViewHolder(final Holder holder, int position) { Bean bean = mDatas.get(position); holder.nick.setText(bean.nick); holder.desc.setText(bean.desc); holder.image.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { mHelper.startDrag(holder); } return false; } }); }
@Override public int getItemCount() { return mDatas == null ? 0 : mDatas.size(); }
@Override public void onMove(int srcPos, int targetPos) { Collections.swap(mDatas, srcPos, targetPos); notifyItemMoved(srcPos, targetPos); } @Override public void onRemove(int pos) { mDatas.remove(pos); notifyItemRemoved(pos); } }
|
重点来了
MyHelpCall代码:
实际上也比较简单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
| public class MyHelperCall extends ItemTouchHelper.Callback {
private final ItemMoveListener mItemMoveListener;
public MyHelperCall(ItemMoveListener listener) { this.mItemMoveListener = listener; }
@Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; int swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; return makeMovementFlags(dragFlags, swipeFlags); }
@Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder srcHolder, RecyclerView.ViewHolder targetHolder) { if (srcHolder.getItemViewType() != targetHolder.getItemViewType()) return false; mItemMoveListener.onMove(srcHolder.getAdapterPosition(), targetHolder.getAdapterPosition()); return true; } @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { mItemMoveListener.onRemove(viewHolder.getAdapterPosition()); }
@Override public void onSelectedChanged(RecyclerView.ViewHolder holder, int actionState) { if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) { holder.itemView.setBackgroundColor( holder.itemView.getContext().getResources().getColor(R.color.selectColor)); } super.onSelectedChanged(holder, actionState); }
@Override public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder , float dX, float dY, int actionState, boolean isCurrentlyActive) { super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { Log.e("test", "dx:" + dX + ",dY:" + dY); viewHolder.itemView.setAlpha(1 - Math.abs(dX) / viewHolder.itemView.getWidth()); viewHolder.itemView.setScaleX(1 - Math.abs(dX) / viewHolder.itemView.getWidth()); viewHolder.itemView.setScaleY(1 - Math.abs(dX) / viewHolder.itemView.getWidth()); } } @Override public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder holder) { super.clearView(recyclerView, holder); holder.itemView.setBackgroundColor(Color.WHITE); holder.itemView.setAlpha(1); holder.itemView.setScaleX(1); holder.itemView.setScaleY(1); } @Override public boolean isItemViewSwipeEnabled() { return super.isItemViewSwipeEnabled(); }
@Override public boolean isLongPressDragEnabled() { return super.isLongPressDragEnabled(); } }
|