You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RecyclerView(GridLayoutManager)长按拖拽排序时抖动效果实现

实现RecyclerView拖拽排序时的抖动动画效果

我来帮你搞定这个抖动动画的需求,结合你已经实现的拖拽排序功能,咱们分几步来落地:

1. 创建抖动动画资源文件

首先在res/anim目录下新建shake.xml,定义轻量的抖动旋转动画:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="100"
    android:fromDegrees="-2"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:toDegrees="2" />

这个动画会让View在±2度之间来回旋转,无限循环,刚好是咱们要的“抖动”视觉效果。

2. 在Adapter的ViewHolder中绑定动画控制逻辑

在你的Adapter的ViewHolder里,给itemView添加长按监听触发动画,同时封装启停动画的方法:

class YourItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    // 初始化你的控件...

    init {
        // 长按触发抖动
        itemView.setOnLongClickListener {
            startShake()
            true // 返回true让ItemTouchHelper的拖拽事件正常触发
        }
    }

    // 启动抖动动画
    fun startShake() {
        val shakeAnim = AnimationUtils.loadAnimation(itemView.context, R.anim.shake)
        itemView.startAnimation(shakeAnim)
    }

    // 停止抖动动画
    fun stopShake() {
        itemView.clearAnimation()
    }
}

如果是Java开发,把语法转成对应的Java写法即可,逻辑完全一致。

3. 结合ItemTouchHelper回调控制动画生命周期

你已经实现了拖拽排序,肯定有ItemTouchHelper.Callback的子类,咱们在这个回调里监听拖拽的开始与结束状态,确保动画在拖拽全程保持,放置后停止:

class YourDragCallback(private val adapter: YourAdapter) : ItemTouchHelper.Callback() {
    // 你的已有实现:getMovementFlags、onMove等方法...

    override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
        super.onSelectedChanged(viewHolder, actionState)
        // 拖拽开始时,确保动画持续播放
        if (actionState == ItemTouchHelper.ACTION_STATE_DRAG && viewHolder is YourItemViewHolder) {
            viewHolder.startShake()
        }
    }

    override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
        super.clearView(recyclerView, viewHolder)
        // 拖拽结束、item放置完成时,停止抖动
        if (viewHolder is YourItemViewHolder) {
            viewHolder.stopShake()
        }
    }
}

这里的clearView方法会在拖拽结束、item回到最终位置时被调用,刚好用来终止动画;onSelectedChanged则在拖拽启动时触发,避免长按动画意外中断。

4. 补充复用item的动画重置逻辑

为了避免RecyclerView复用item时,旧的抖动动画被带到新的item上,在onBindViewHolder里先重置动画:

override fun onBindViewHolder(holder: YourItemViewHolder, position: Int) {
    // 先停止可能残留的动画
    holder.stopShake()
    // 再绑定你的数据...
}

这样一套流程下来,用户长按item时会立刻开始抖动,拖拽过程中持续保持抖动效果,松开item完成排序后,抖动会马上停止,完全匹配你的需求!

内容的提问来源于stack exchange,提问作者shine_joseph

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:19:57