您的位置:首页 > 移动开发 > Android开发

RecyclerView之ItemTouchHelper仿今日头条频道管理拖动

2017-01-03 20:21 585 查看
Github地址:这里写链接内容

ItemTouchHelper的使用

ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
return 0;
}

@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}

@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {

}

@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
super.onSelectedChanged(viewHolder, actionState);
}

@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
}

@Override
public boolean isLongPressDragEnabled() {
return super.isLongPressDragEnabled();
}
});
itemTouchHelper.attachToRecyclerView(recyclerView);


首先创建ItemTouchHelper对象,它的构造方法需要一个ItemTouchHelper.Callback,重写它的几个方法:

//dragFlags确定拖动方向,swipeFlags确定滑动删除
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
int swipeFlags = 0;
return makeMovementFlags(dragFlags,swipeFlags);
}


//当发生拖动时候的回调方法
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
if(viewHolder.getItemViewType()!=target.getItemViewType()){
return false;
}
if(recyclerView.getAdapter() instanceof OnItemMovedListener){
OnItemMovedListener onItemMovedListener = (OnItemMovedListener) recyclerView.getAdapter();
onItemMovedListener.onItemMoved(viewHolder.getAdapterPosition(),target.getAdapterPosition());
}
return true;
}


//当点击item时的回调,这里是将item放大
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
super.onSelectedChanged(viewHolder, actionState);
if(actionState == ItemTouchHelper.ACTION_STATE_IDLE){
return;
}
viewHolder.itemView.setScaleX(1.2f);
viewHolder.itemView.setScaleY(1.2f);
}


//松手后的回调,这里将view还原到初始大小
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
viewHolder.itemView.setScaleX(1f);
viewHolder.itemView.setScaleY(1f);
}


//是否开启长按拖动,因为不是所有的item都支持长按拖动,这里设置为false,在之后可以调用itemTouchHelper.startDrag()开始拖动
@Override
public boolean isLongPressDragEnabled() {
return false;
}


定义一个接口用来处理拖时的数据及UI变化

public interface OnItemMovedListener {
void onItemMoved(int fromPosition,int toPosition);
}


接下来是Adapter的代码编写,

首先adapter实现OnItemMovedListener接口来处理数据交换和recyclerview的UI动效:

@Override
public void onItemMoved(int fromPosition, int toPosition) {
ChannelEntity channelEntity = myChannels.get(fromPosition - 1);
myChannels.remove(fromPosition - 1);
myChannels.add(toPosition - 1, channelEntity);
notifyItemMoved(fromPosition, toPosition);
}


其他重写getItemViewType、onCreateViewHolder、onBindViewHolder方法没有特别之处,不做赘述,详情见github上的代码。

接下来主要讲解一下删除已选的item和添加item的动画实现。

主要是通过view.getDrawingCache()获取点击的View的bitmap,new一个ImageView设置src为刚刚生成的bitmap,再对其进行translateAnimation.

删除item的动画实现:

@Override
public void onClick(View v) {
int position = myChannelViewHolder.getAdapterPosition();
RecyclerView recyclerView = (RecyclerView) parent;
if (isEditMode) {
View targetView = recyclerView.getLayoutManager().findViewByPosition(myChannels.size() + 2);
View currentView = recyclerView.getLayoutManager().findViewByPosition(position);
//如果目标targetView(indexOfChild>=0)在屏幕内,则需要添加动画效果;
// 如果不在屏幕内,那么recyclerview的notifyItemMoved会有向目标移动的动画
if (recyclerView.indexOfChild(targetView) >= 0) {
//目标位置的坐标
float targetX, targetY;
int spanCount = ((GridLayoutManager) (recyclerView.getLayoutManager())).getSpanCount();
//如果已选的item在最后一行的第一个位置,那么移动后高度会变化,所以目标View就是当前View的下一个view
if ((myChannels.size() - 1) % spanCount == 0) {
View preTargetView = recyclerView.getLayoutManager().findViewByPosition(myChannels.size() + 1);
targetX = preTargetView.getLeft();
targetY = preTargetView.getTop();
} else {
targetX = targetView.getLeft();
targetY = targetView.getTop();
}
moveMineToOthers(myChannelViewHolder);
startAnimation((RecyclerView) parent, currentView, targetX, targetY);

} else {
moveMineToOthers(myChannelViewHolder);

}
}
}


未完待续
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐