相关阅读:
吊炸天!74款APP完整源码!
2017年,你一定需要的25个Android第三方库
阿里两个最新Android开源库,Android开发者的福音
作者:Code4Android
http://android.jobbole.com/85372 (
源码下载见文末
)
前言
从Android 5.0开始,谷歌推出了新的控件RecyclerView,相对于早它之前的ListView,优点多多,功能强大,也给我们的开发着提供了极大的便利,今天自己学习一下RecyclerView轻松实现滑动删除及拖拽的效果,如下图。
相信研究过RecyclerView的同学,应该很清楚该怎么实现这样的效果,若是用ListView,这样的效果实现起来可能就有点麻烦,但是在强大的RecyclerView面前这样的的效果只需很少的代码,因为谷歌给我们提供了强大的工具类ItemTouchHelper,它已经处理了关于RecyclerView拖动和滑动的实现,并且我们可以在其中实现我们自己的动画,以及定制我们想要的效果。
ItemTouchHelper.Callback有几个重要的抽象方法,我们继承该抽象类,并重写抽象方法。它是我们实现滑动和拖拽重要的回调。
int
getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)
该方法返回一个整数,用来指定拖拽和滑动在哪个方向是被允许的。在其中使用makeMovementFlags(int dragFlags, int swipeFlags)返回,该方法第一个参数用来指定拖动,第二个参数用来指定滑动。对于方向参数有6种
ItemTouchHelper
.
UP
//滑动拖拽向上方向
ItemTouchHelper
.
DOWN
//向下
ItemTouchHelper
.
LEFT
//向左
ItemTouchHelper
.
RIGHT
//向右
ItemTouchHelper
.
START
//依赖布局方向的水平开始方向
ItemTouchHelper
.
END
//依赖布局方向的水平结束方向
boolean
onMove
(
RecyclerView
recyclerView
,
RecyclerView
.
ViewHolder
viewHolder
,
RecyclerView
.
ViewHolder
target
)
onMove方法是拖拽的回调,参数viewHolder是拖动的Item,target是拖动的目标位置的Item,该方法如果返回true表示切换了位置,反之返回false。
void
onSwiped(RecyclerView.ViewHolder viewHolder,
int
direction)
onSwiped方法为Item滑动回调,viewHolder为滑动的item,direction为滑动的方向。
上面三个方法是必须重写的方法,当然还有其它一些可供选择的方法。
/**
* Item是否支持长按拖动
*
* @return
* true 支持长按操作
* false 不支持长按操作
*/
boolean
isLongPressDragEnabled
()
/**
* Item是否支持滑动
*
* @return
* true 支持滑动操作
* false 不支持滑动操作
*/
boolean
isItemViewSwipeEnabled
()
/**
* 移动过程中绘制Item
*
* @param c
* @param recyclerView
* @param viewHolder
* @param dX
* X轴移动的距离
* @param dY
* Y轴移动的距离
* @param actionState
* 当前Item的状态
* @param isCurrentlyActive
* 如果当前被用户操作为true,反之为false
*/
onChildDraw
(
Canvas
c
,
RecyclerView
recyclerView
,
RecyclerView
.
ViewHolder
viewHolder
,
float
dX
,
float
dY
,
int
actionState
,
boolean
isCurrentlyActive
)
需要注意的是,如果我们想实现拖动或者滑动必须将上面是否支持拖动或者滑动的方法返回true,否则onMove或者onSwiped方法不会执行。
功能实现
adapter
=
new
CustomAdapter
(
getActivity
(),
strings
);
recycleview
.
setAdapter
(
adapter
);
ItemTouchHelper
.
Callback
callback
=
new
RecycleItemTouchHelper
(
adapter
);
ItemTouchHelper
itemTouchHelper
=
new
ItemTouchHelper
(
callback
);
itemTouchHelper
.
attachToRecyclerView
(
recycleview
);
对于ItemTouchHelper 构造方法接收一个ItemTouchHelper.Callback参数,而这个Callback就是我们在在上述讲到的工具类,初始化ItemTouchHelper 后通过其attachToRecyclerView(@Nullable RecyclerView recyclerView)方法将我们实现的ItemTouchHelper.Callback和RecyclerView关联,最终达到我们的效果,代码看起来是不是很简单,接下来我们看下我们自定义的Callback。
package
com
.
example
.
xh
.
adapter
;
import
android
.
content
.
res
.
Resources
;
import
android
.
graphics
.
Bitmap
;
import
android
.
graphics
.
BitmapFactory
;
import
android
.
graphics
.
Canvas
;
import
android
.
graphics
.
Paint
;
import
android
.
graphics
.
Rect
;
import
android
.
support
.
v7
.
widget
.
RecyclerView
;
import
android
.
support
.
v7
.
widget
.
helper
.
ItemTouchHelper
;
import
android
.
util
.
Log
;
import
android
.
view
.
View
;
import
com
.
example
.
xh
.
R
;
import
com
.
example
.
xh
.
utils
.
MyApplication
;
/**
* Created by xiehui on 2017/2/23.
*/
public
class
RecycleItemTouchHelper
extends
ItemTouchHelper
.
Callback
{
private
static
final
String
TAG
=
"RecycleItemTouchHelper"
;
private
final
ItemTouchHelperCallback
helperCallback
;
public
RecycleItemTouchHelper
(
ItemTouchHelperCallback
helperCallback
)
{
this
.
helperCallback
=
helperCallback
;
}
/**
* 设置滑动类型标记
*
* @param recyclerView
* @param viewHolder
* @return
* 返回一个整数类型的标识,用于判断Item那种移动行为是允许的
*/
@
Override
public
int
getMovementFlags
(
RecyclerView
recyclerView
,
RecyclerView
.
ViewHolder
viewHolder
)
{
Log
.
e
(
TAG
,
"getMovementFlags: "
);
//START 右向左 END左向右 LEFT 向左 RIGHT向右 UP向上
//如果某个值传0,表示不触发该操作,次数设置支持上下拖拽,支持向右滑动
return
makeMovementFlags
(
ItemTouchHelper
.
UP
|
ItemTouchHelper
.
DOWN
,
ItemTouchHelper
.
END
);
}
/**
* Item是否支持长按拖动
*
* @return
* true 支持长按操作
* false 不支持长按操作
*/
@
Override
public
boolean
isLongPressDragEnabled
()
{
return
super
.
isLongPressDragEnabled
();
}
/**
* Item是否支持滑动
*
* @return
* true 支持滑动操作
* false 不支持滑动操作
*/
@
Override
public
boolean
isItemViewSwipeEnabled
()
{
return
super
.
isItemViewSwipeEnabled
();
}
/**
* 拖拽切换Item的回调
*
* @param recyclerView
* @param viewHolder
* @param target
* @return
* 如果Item切换了位置,返回true;反之,返回false
*/
@
Override
public
boolean
onMove
(
RecyclerView
recyclerView
,
RecyclerView
.
ViewHolder
viewHolder
,
RecyclerView
.
ViewHolder
target
)
{
Log
.
e
(
TAG
,
"onMove: "
);
helperCallback
.
onMove
(
viewHolder
.
getAdapterPosition
(),
target
.
getAdapterPosition
());
return
true
;
}