ItemTouchHelper 实现交互动画

  • desc  : 自定义ItemTouchHelper
    
  • revise: 参考严正杰大神博客:https://blog.csdn.net/yanzhenjie1003/article/details/51935982
    

*/

public class ItemTouchHelpCallback extends ItemTouchHelper.Callback {

/**

  • Item操作的回调,去更新UI和数据源

*/

private OnItemTouchCallbackListener onItemTouchCallbackListener;

/**

  • 是否可以拖拽

*/

private boolean isCanDrag = false;

/**

  • 是否可以被滑动

*/

private boolean isCanSwipe = false;

/**

  • 按住拖动item的颜色

*/

private int color = 0;

public ItemTouchHelpCallback(OnItemTouchCallbackListener onItemTouchCallbackListener) {

this.onItemTouchCallbackListener = onItemTouchCallbackListener;

}

/**

  • 设置是否可以被拖拽

  • @param canDrag 是true,否false

*/

public void setDragEnable(boolean canDrag) {

isCanDrag = canDrag;

}

/**

  • 设置是否可以被滑动

  • @param canSwipe 是true,否false

*/

public void setSwipeEnable(boolean canSwipe) {

isCanSwipe = canSwipe;

}

/**

  • 设置按住拖动item的颜色

  • @param color 颜色

*/

public void setColor(@ColorInt int color){

this.color = color;

}

/**

  • 当Item被长按的时候是否可以被拖拽

  • @return true

*/

@Override

public boolean isLongPressDragEnabled() {

return isCanDrag;

}

/**

  • Item是否可以被滑动(H:左右滑动,V:上下滑动)

  • isItemViewSwipeEnabled()返回值是否可以拖拽排序,true可以,false不可以

  • @return true

*/

@Override

public boolean isItemViewSwipeEnabled() {

return isCanSwipe;

}

/**

  • 当用户拖拽或者滑动Item的时候需要我们告诉系统滑动或者拖拽的方向

  • 动作标识分:dragFlags和swipeFlags

  • dragFlags:列表滚动方向的动作标识(如竖直列表就是上和下,水平列表就是左和右)

  • wipeFlags:与列表滚动方向垂直的动作标识(如竖直列表就是左和右,水平列表就是上和下)

  • 思路:如果你不想上下拖动,可以将 dragFlags = 0

  •  如果你不想左右滑动,可以将 swipeFlags = 0
    
  •  最终的动作标识(flags)必须要用makeMovementFlags()方法生成
    

*/

@Override

public int getMovementFlags(@NonNull RecyclerView recyclerView,

@NonNull RecyclerView.ViewHolder viewHolder) {

RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();

if (layoutManager instanceof GridLayoutManager) {

// flag如果值是0,相当于这个功能被关闭

int dragFlag = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT

| ItemTouchHelper.UP | ItemTouchHelper.DOWN;

int swipeFlag = 0;

// create make

return makeMovementFlags(dragFlag, swipeFlag);

} else if (layoutManager instanceof LinearLayoutManager) {

LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;

int orientation = linearLayoutManager.getOrientation();

int dragFlag = 0;

int swipeFlag = 0;

// 为了方便理解,相当于分为横着的ListView和竖着的ListView

// 如果是横向的布局

if (orientation == LinearLayoutManager.HORIZONTAL) {

swipeFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN;

dragFlag = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;

} else if (orientation == LinearLayoutManager.VERTICAL) {

// 如果是竖向的布局,相当于ListView

dragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN;

swipeFlag = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;

}

//第一个参数是拖拽flag,第二个是滑动的flag

return makeMovementFlags(dragFlag, swipeFlag);

}

return 0;

}

/**

  • 当Item被拖拽的时候被回调

  • @param recyclerView recyclerView

  • @param srcViewHolder 当前被拖拽的item的viewHolder

  • @param targetViewHolder 当前被拖拽的item下方的另一个item的viewHolder

  • @return 是否被移动

*/

@Override

public boolean onMove(@NonNull RecyclerView recyclerView,

@NonNull RecyclerView.ViewHolder srcViewHolder,

@NonNull RecyclerView.ViewHolder targetViewHolder) {

if (onItemTouchCallbackListener != null) {

int srcPosition = srcViewHolder.getAdapterPosition();

int targetPosition = targetViewHolder.getAdapterPosition();

return onItemTouchCallbackListener.onMove(srcPosition, targetPosition);

}

return false;

}

/**

  • 当item侧滑出去时触发(竖直列表是侧滑,水平列表是竖滑)

  • @param viewHolder viewHolder

  • @param direction 滑动的方向

*/

@Override

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

if (onItemTouchCallbackListener != null) {

onItemTouchCallbackListener.onSwiped(viewHolder.getAdapterPosition());

}

}

/**

  • 当item被拖拽或侧滑时触发

  • @param viewHolder viewHolder

  • @param actionState 当前item的状态

*/

@Override

public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {

super.onSelectedChanged(viewHolder, actionState);

//不管是拖拽或是侧滑,背景色都要变化

if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {

if (color==0){

viewHolder.itemView.setBackgroundColor(viewHolder.itemView.getContext()

.getResources().getColor(android.R.color.darker_gray));

}else {

viewHolder.itemView.setBackgroundColor(color);

}

}

}

/**

  • 当item的交互动画结束时触发

  • @param recyclerView recyclerView

  • @param viewHolder viewHolder

*/

@Override

public void clearView(@NonNull RecyclerView recyclerView,

@NonNull RecyclerView.ViewHolder viewHolder) {

super.clearView(recyclerView, viewHolder);

viewHolder.itemView.setBackgroundColor(viewHolder.itemView.getContext().getResources()

.getColor(android.R.color.white));

viewHolder.itemView.setAlpha(1);

viewHolder.itemView.setScaleY(1);

}

@Override

public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView,

@NonNull 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) {

float value = 1 - Math.abs(dX) / viewHolder.itemView.getWidth();

viewHolder.itemView.setAlpha(value);

viewHolder.itemView.setScaleY(value);

}

}

public interface OnItemTouchCallbackListener {

/**

  • 当某个Item被滑动删除的时候

  • @param adapterPosition item的position

*/

void onSwiped(int adapterPosition);

/**

  • 当两个Item位置互换的时候被回调

  • @param srcPosition 拖拽的item的position

  • @param targetPosition 目的地的Item的position

  • @return 开发者处理了操作应该返回true,开发者没有处理就返回false

*/

boolean onMove(int srcPosition, int targetPosition);

}

}

最后

如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足。谢谢。

欢迎大家一起交流讨论啊~
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
m srcPosition 拖拽的item的position

  • @param targetPosition 目的地的Item的position

  • @return 开发者处理了操作应该返回true,开发者没有处理就返回false

*/

boolean onMove(int srcPosition, int targetPosition);

}

}

最后

如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足。谢谢。

[外链图片转存中…(img-X1vYo6hm-1714758574247)]

欢迎大家一起交流讨论啊~
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值