DragRecyclerView-master

1,今天和大家一起实现RecyclerView可拖拽Item,主要是使用RecyclerView结合ItemTouchHelper来实现的,来看一下效果

 

2,看一下怎么实现的呢,很简单,只需要给recyclerView添加一个ItemTouchHelper对象就行

1
2
mItemTouchHelper = new ItemTouchHelper( new ItemTouchHelper.Callback() );
mItemTouchHelper.attachToRecyclerView(mRecyclerView);

 构造方法中需要一个CallBack对象,适用于拖拽或者剔除时的回调方法,所以我们主要是要重写CallBack中的相应方法,处理响应的逻辑

   首先来自定义一个CallBack类,继承与ItemTouchHepler.Callback()对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
  
}
 
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
   
   
}
 
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
 
}

  首先说一下getMovementFlags(),这个方法是设置是否滑动时间,以及拖拽的方向,所以在这里需要判断一下是列表布局还是网格布局,如果是列表布局的话则拖拽方向为DOWN和UP,如果是网格布局的话则是DOWN和UP和LEFT和RIGHT,对应这个方法的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
             public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                 if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
                     final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN |
                             ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
                     final int swipeFlags = 0 ;
                     return makeMovementFlags(dragFlags, swipeFlags);
                 } else {
                     final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
                     final int swipeFlags = 0 ;
                     return makeMovementFlags(dragFlags, swipeFlags);
                 }
             }

  而onMove()方法则是我们在拖动的时候不断回调的方法,在这里我们需要将正在拖拽的item和集合的item进行交换元素,然后在通知适配器更新数据,也很简单,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
     //得到当拖拽的viewHolder的Position
     int fromPosition = viewHolder.getAdapterPosition();
     //拿到当前拖拽到的item的viewHolder
     int toPosition = target.getAdapterPosition();
     if (fromPosition < toPosition) {
         for ( int i = fromPosition; i < toPosition; i++) {
             Collections.swap(datas, i, i + 1 );
         }
     } else {
         for ( int i = fromPosition; i > toPosition; i--) {
             Collections.swap(datas, i, i - 1 );
         }
     }
     myAdapter.notifyItemMoved(fromPosition, toPosition);
     return true ;
}

  onSwiped()是替换后调用的方法,可以不用管。然后我们希望在拖拽的时候将被拖拽的Item高亮,这样用户体验要好很多,所以我们要重写CallBack对象中的onSelectedChanged()和clearView()方法,在选中的时候设置高亮背景色,在完成的时候移除高亮背景色,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
  * 长按选中Item的时候开始调用
  *
  * @param viewHolder
  * @param actionState
  */
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
     if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
         viewHolder.itemView.setBackgroundColor(Color.LTGRAY);
     }
     super .onSelectedChanged(viewHolder, actionState);
}
 
/**
  * 手指松开的时候还原
  * @param recyclerView
  * @param viewHolder
  */
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
     super .clearView(recyclerView, viewHolder);
     viewHolder.itemView.setBackgroundColor( 0 );
}

  这样就实现了我们的基本要求,但是实际功能中有可能存在,排头前两个的不需改变它的顺序,即有些item允许拖拽,有些则不允许,所以我们需要重写isLongPressDragEnabled()设置不允许长按拖拽

1
2
3
4
5
6
7
8
/**
  * 重写拖拽不可用
  * @return
  */
@Override
public boolean isLongPressDragEnabled() {
     return false ;
}

  然后在重写RecycleView的长按监听(这个要自己写个接口去实现),在返回的长按方法中判断是否为不可拖拽的item,若不是,则调用ItemTouchHelper的startDrag()方法,逻辑出入如下:

1
2
3
4
5
6
7
8
@Override
  public void onItemLongClick(RecyclerView.ViewHolder vh) {
      //判断被拖拽的是否是前两个,如果不是则执行拖拽
      if (vh.getLayoutPosition() != 0 && vh.getLayoutPosition() != 1 ) {
          mItemTouchHelper.startDrag(vh);
 
      }
  }

  为了功耗的用户体验 我们可以在长按的时候添加震动,添加权限

1
<uses-permission android:name= "android.permission.VIBRATE" />

  调用方法:

1
2
3
4
//获取系统震动服务
  Vibrator vib = (Vibrator) getSystemService(Service.VIBRATOR_SERVICE);
//震动70毫秒
  vib.vibrate( 70 );
下载地址:http://download.csdn.net/download/qq_16097005/9896451
点我下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值