1、相关知识点:
(1)RecyclerView的基本用法:布局、适配器、数据绑定
(2)RecyclerView的分割线添加
(3)RecyclerView的item动画添加
(4)RecyclerView的手势监听
(5)回调机制
2、核心思想:
(1)为什么选择RecyclerView,因为它除了可以实现ListView、GridView、瀑布流布局之间的状态切换,同时将以前列表组件的中适配器、Activity、ViewHolder、事件处理等属性进行了高度解耦。
(2)ItemTouchHelper监听列表被触摸事件,上下方向为拖拽和活动列表行为,其中后者属于系统默认行为不需要处理,如果是拖拽排序,通过回调item中相应位置的数据进行位置互换,同时刷新列表。
(3)同样,左右滑动代码删除行为,通过手势监听,回调适配器对相关item的数据在列表中进行相应的删除操作,同时刷新列表。
3、核心技术:
(1)RecyclerView的触摸事件绑定
(2)回调机制实现用户的UI交互
4、核心代码:
(1)RecyclerView初始化设置:
public class MainActivity extends FragmentActivity implements startDragListener {
RecyclerView drag_swipe_recyclerView;
ItemTouchHelper helper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//构造虚拟数据
List<String> data = new ArrayList<String>();
for (char i= 'A'; i<='Z'; ++i)
{
data.add(""+i);
}
//设置为线性列表布局
drag_swipe_recyclerView = (RecyclerView)findViewById(R.id.drag_swipe_recyclerView);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
//设置为垂直滑动的列表
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
drag_swipe_recyclerView.setLayoutManager(layoutManager);
//设置各个布局高度一致加快加载速度
drag_swipe_recyclerView.setHasFixedSize(true);
//初始化列表
DragSwipeListAdapter adapter = new DragSwipeListAdapter(data, this);
drag_swipe_recyclerView.setAdapter(adapter);
//设置列表删除和添加时的动画
drag_swipe_recyclerView.setItemAnimator(new DefaultItemAnimator());
//设置列表每个Item的间隔线
drag_swipe_recyclerView.addItemDecoration(new DividerItemDecoration(this, OrientationHelper.VERTICAL));
// 设置点击事件
adapter.setItemClickListener(new onItemClickListener() {
@Override
public void onItemClick(Object obj) {
Toast.makeText(MainActivity.this, "点击了"+obj.toString(), Toast.LENGTH_SHORT).show();
}
});
//设置触摸监听事件
ItemTouchHelper.Callback callback = new DraySwipeTouchCallBack(adapter);
helper = new ItemTouchHelper(callback);
helper.attachToRecyclerView(drag_swipe_recyclerView);
}
@Override
public void startDragListener(RecyclerView.ViewHolder holder) {
if (helper != null)
{
helper.startDrag(holder);
}
}
}
/**
* Created by czh on 2016/5/12.14:26.
* Tip: Android_Study
*/
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
//采用系统内置的风格的分割线
private static final int[] attrs=new int[]{android.R.attr.listDivider};
private Drawable mDivider;
private int orientation;
public DividerItemDecoration(Context context, int orientation) {
TypedArray typedArray=context.obtainStyledAttributes(attrs);
mDivider=typedArray.getDrawable(0);
typedArray.recycle();
this.orientation=orientation;
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
drawHDeraction(c,parent);
drawVDeraction(c,parent);
}
/**
* 绘制水平方向的分割线
* @param c
* @param parent
*/
private void drawHDeraction(Canvas c,RecyclerView parent){
int left=parent.getPaddingLeft();
int right=parent.getWidth()-parent.getPaddingRight();
int childCount=parent.getChildCount();
for(int i=0;i<childCount;i++){
View child=parent.getChildAt(i);
RecyclerView.LayoutParams layoutParams=(RecyclerView.LayoutParams)child.getLayoutParams();
int top=child.getBottom()+layoutParams.bottomMargin;
int bottom=top+mDivider.getIntrinsicHeight();
mDivider.setBounds(left,top,right,bottom);
mDivider.draw(c);
}
}
/**
* 绘制垂直方向的分割线
* @param c
* @param parent
*/
private void drawVDeraction(Canvas c,RecyclerView parent){
int top=parent.getPaddingTop();
int bottom=parent.getHeight()-parent.getPaddingBottom();
int childCount=parent.getChildCount();
for(int i=0;i<childCount;i++){
View child=parent.getChildAt(i);
RecyclerView.LayoutParams layoutParams=(RecyclerView.LayoutParams)child.getLayoutParams();
int left=child.getRight()+layoutParams.rightMargin;
int right=left+mDivider.getIntrinsicWidth();
mDivider.setBounds(left,top,right,bottom);
mDivider.draw(c);
}
}
@Override
public void getItemOffsets(Rect outRect,View view, RecyclerView parent, RecyclerView.State state) {
if(OrientationHelper.HORIZONTAL==orientation){
outRect.set(0, 0,mDivider.getIntrinsicWidth(), 0);
}else {
outRect.set(0, 0, 0,mDivider.getIntrinsicHeight());
}
}
}
(3)事件处理
/**
* Created by czh on 2016/5/10.
* 拖拽排序+滑动删除列表手势监听事件
*/
public class DraySwipeTouchCallBack extends Callback {
private ISuperItemOpeartion itemMove;
public DraySwipeTouchCallBack(ISuperItemOpeartion adapter) {
this.itemMove = adapter;
}
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
//设置列表滑动方向
int dragFlag = ItemTouchHelper.DOWN|ItemTouchHelper.UP;
int swipeFlag = ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT;
return makeMovementFlags(dragFlag, swipeFlag);
}
/**
*
* @param recyclerView
* @param viewHolder
* @param target
* @return
*/
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
//更换RecyclerView中两个对象的在数据的位置
//更新RecyclerView
itemMove.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return false;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
itemMove.onItemSwipe(viewHolder.getAdapterPosition());
}
}
如果想要更深入的理解ItemTouchHelper能做什么事情,请查看我的另一篇关于ItemTouchHelper解析的博客:http://blog.csdn.net/dnnis/article/details/51743904
源码地址:https://github.com/PerterJu/DragSwipeRecyclerView.git