如何为ImageView添加波纹动画?加载图片前展示动画失败
解决ImageView加载前的波纹动画问题
原代码的问题
- RippleDrawable是为触摸交互设计的组件,不会自动播放波纹效果,必须触发触摸事件才会产生波纹
- AnimationDrawable仅添加了单个帧,没有帧序列的变化逻辑,无法形成可见的动画效果
方案一:用ObjectAnimator实现自动波纹扩散动画
通过缩放+透明度的组合动画,模拟无限循环的波纹扩散效果,无需依赖触摸事件。
步骤1:创建波纹形状Drawable
在res/drawable目录下新建ripple_loading.xml:
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <solid android:color="#80000000"/> <!-- 半透明黑色,可根据需求调整颜色 --> </shape>
步骤2:调整布局结构
给ImageView添加一个覆盖层View作为动画载体,避免动画影响图片显示:
<FrameLayout android:layout_width="100dp" android:layout_height="100dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> <ImageView android:id="@+id/image_view" android:layout_width="match_parent" android:layout_height="match_parent" /> <View android:id="@+id/ripple_view" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/ripple_loading"/> </FrameLayout>
步骤3:实现动画逻辑
在代码中配置并启动无限循环动画,图片加载完成后停止并隐藏动画:
ImageView imageView = findViewById(R.id.image_view); View rippleView = findViewById(R.id.ripple_view); // 创建缩放动画:从0.2倍放大到1.5倍 ObjectAnimator scaleX = ObjectAnimator.ofFloat(rippleView, "scaleX", 0.2f, 1.5f); ObjectAnimator scaleY = ObjectAnimator.ofFloat(rippleView, "scaleY", 0.2f, 1.5f); // 创建透明度动画:从完全显示到完全透明 ObjectAnimator alpha = ObjectAnimator.ofFloat(rippleView, "alpha", 1f, 0f); // 组合动画,设置时长与循环规则 AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether(scaleX, scaleY, alpha); animatorSet.setDuration(1500); animatorSet.setRepeatCount(ValueAnimator.INFINITE); animatorSet.setRepeatMode(ValueAnimator.RESTART); animatorSet.start(); // 示例:用Glide加载图片,完成后停止动画 Glide.with(this) .load("你的服务器图片URL") .into(new CustomTarget<Drawable>() { @Override public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { imageView.setImageDrawable(resource); animatorSet.cancel(); rippleView.setVisibility(View.GONE); } @Override public void onLoadCleared(@Nullable Drawable placeholder) {} });
方案二:用AnimationDrawable实现帧动画
如果必须使用AnimationDrawable,需要准备多帧递进的波纹Drawable:
步骤1:创建帧动画配置文件
在res/anim目录下新建ripple_frames.xml:
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> <item android:drawable="@drawable/ripple_frame1" android:duration="300"/> <item android:drawable="@drawable/ripple_frame2" android:duration="300"/> <item android:drawable="@drawable/ripple_frame3" android:duration="300"/> <item android:drawable="@drawable/ripple_frame4" android:duration="300"/> </animation-list>
其中ripple_frame1到ripple_frame4是依次增大、透明度逐渐降低的圆形Drawable。
步骤2:启动帧动画
ImageView imageView = findViewById(R.id.image_view); imageView.setBackgroundResource(R.anim.ripple_frames); AnimationDrawable anim = (AnimationDrawable) imageView.getBackground(); anim.start(); // 图片加载完成后停止并清理动画 // anim.stop(); // imageView.setBackground(null); // imageView.setImageDrawable(加载的图片);
关键注意事项
- 不要用RippleDrawable实现自动播放动画,它的核心定位是触摸反馈
- 图片加载完成后必须停止动画并清理资源,避免内存泄漏
- 若使用第三方图片加载库,可结合其占位图机制简化逻辑,但自定义动画灵活性更高
内容的提问来源于stack exchange,提问作者coderror
相关产品推荐
相关产品推荐

