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

如何让RecyclerView项的抖动动画带延迟无限重复

解决方案

1. 调整抖动动画文件

首先修改res/anim/shake_animation.xml,将其改为单次抖动的完整动画,后续通过定时器控制每隔5秒重复执行:

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <rotate
        android:duration="50"          <!-- 单次旋转的时长(从-2°到2°的时间) -->
        android:fromDegrees="-2"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="9"        <!-- 重复次数,总抖动时长=50*(9+1)=500ms(可按需调整) -->
        android:repeatMode="reverse"
        android:toDegrees="2" />
</set>

如果需要控制单次抖动的总时长,直接计算:总时长 = duration * (repeatCount + 1),比如要单次抖动持续1秒,可设置duration="50"、repeatCount="19"(50*20=1000ms)。

2. 在RecyclerView Adapter中实现定时重复动画

由于RecyclerView存在View复用,必须在绑定View时启动定时任务,回收View时取消任务,避免动画混乱和内存泄漏:

步骤1:定义ViewHolder并持有定时任务

public class YourAdapter extends RecyclerView.Adapter<YourAdapter.ViewHolder> {
    private Context context;
    // 其他成员变量...

    public class ViewHolder extends RecyclerView.ViewHolder {
        private Handler shakeHandler;
        private Runnable shakeRunnable;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            shakeHandler = new Handler(Looper.getMainLooper());
        }
    }

    // Adapter其他方法...
}

步骤2:绑定View时启动定时抖动

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    // 先取消当前View的旧任务,避免复用后重复执行
    holder.shakeHandler.removeCallbacks(holder.shakeRunnable);

    // 定义抖动任务:执行一次抖动动画,5秒后重复
    holder.shakeRunnable = new Runnable() {
        @Override
        public void run() {
            Animation shake = AnimationUtils.loadAnimation(context, R.anim.shake_animation);
            holder.itemView.startAnimation(shake);
            // 5秒后再次触发抖动
            holder.shakeHandler.postDelayed(this, 5000);
        }
    };

    // 立即执行第一次抖动
    holder.shakeHandler.post(holder.shakeRunnable);
}

步骤3:回收View时取消定时任务

@Override
public void onViewRecycled(@NonNull ViewHolder holder) {
    super.onViewRecycled(holder);
    // 取消任务,避免内存泄漏和无效动画
    holder.shakeHandler.removeCallbacks(holder.shakeRunnable);
}

3. 可选:用ValueAnimator实现更灵活的抖动

如果觉得XML动画不够灵活,可直接用代码实现抖动,还能在动画结束后自动重置View状态:

private void startShakeAnimation(View view) {
    ValueAnimator animator = ValueAnimator.ofFloat(-2f, 2f);
    animator.setDuration(50);
    animator.setRepeatCount(9);
    animator.setRepeatMode(ValueAnimator.REVERSE);
    
    animator.addUpdateListener(animation -> {
        float rotateAngle = (float) animation.getAnimatedValue();
        view.setRotation(rotateAngle);
    });
    
    // 动画结束/取消时重置旋转角度
    animator.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {}
        @Override
        public void onAnimationEnd(Animator animation) {
            view.setRotation(0);
        }
        @Override
        public void onAnimationCancel(Animator animation) {
            view.setRotation(0);
        }
        @Override
        public void onAnimationRepeat(Animator animation) {}
    });
    
    animator.start();
}

然后在shakeRunnable中替换为调用这个方法即可:

holder.shakeRunnable = new Runnable() {
    @Override
    public void run() {
        startShakeAnimation(holder.itemView);
        holder.shakeHandler.postDelayed(this, 5000);
    }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 07:05:50