TranslateAnimation执行时如何让ImageView在原始位置保持可见
问题根因
你当前使用的是Android传统视图动画(View Animation)框架,这类动画仅临时修改控件的绘制矩阵,不会改变控件真实的布局位置。动画运行过程中,系统仅会在动画计算出的偏移位置绘制控件内容,原始布局位置不会触发控件重绘,因此会出现原位置空白的现象。setFillAfter(true)的作用仅是让动画结束后控件保持最终偏移的绘制状态,无法解决动画过程中原位置不显示的问题。
实现方案
方案1:适配现有视图动画代码,原位置添加同状态副本
如果要保留你当前的视图动画逻辑,只需要在动画启动前,在原ImageView的位置添加一个视觉完全一致的副本控件,原控件执行平移动画,就能实现原位置持续可见、动画位移动效正常的效果:
// 创建和原ImageView视觉完全一致的副本 ImageView originPlaceHolder = new ImageView(context); originPlaceHolder.setImageDrawable(myImage.getDrawable()); // 同步原控件的布局参数、缩放类型等属性 originPlaceHolder.setLayoutParams(myImage.getLayoutParams()); originPlaceHolder.setScaleType(myImage.getScaleType()); originPlaceHolder.setAlpha(myImage.getAlpha()); // 将副本添加到原控件在父容器中的位置 ViewGroup parentContainer = (ViewGroup) myImage.getParent(); int childIndex = parentContainer.indexOfChild(myImage); parentContainer.addView(originPlaceHolder, childIndex); // 原有动画逻辑无需修改 animation.setDuration(1000); animation.setFillAfter(true); myImage.startAnimation(animation);
如果动画执行完成后不需要保留原位置的占位,在动画结束的回调中移除originPlaceHolder即可;如果需要控件最终停留在动画结束位置,动画结束后先更新原控件的真实布局参数到对应坐标,再清除动画、移除占位副本即可,避免出现视图动画常见的点击区域和显示位置不匹配的问题。
方案2:替换为属性动画(推荐长期使用)
如果你的需求不是“原位置保留影像、控件做位移动效”,只是想实现控件平移效果,直接废弃旧的视图动画,改用属性动画即可。属性动画会真实修改控件的布局属性,从根本上避免绘制位置和实际位置分离、原位置空白的问题:
// 示例:X轴方向向右平移300像素,时长1000ms ObjectAnimator translateAnimation = ObjectAnimator.ofFloat(myImage, "translationX", 0f, 300f); translateAnimation.setDuration(1000); translateAnimation.start();
属性动画不需要调用setFillAfter,动画结束后控件会自动保持在最终属性位置,且点击区域和显示位置完全一致,没有视图动画的固有bug。
内容的提问来源于stack exchange,提问作者Franklyn Oreben
相关产品推荐
相关产品推荐

