TranslateAnimation首次显示按钮时无动画效果问题咨询
首次点击显示按钮时动画失效的原因与解决方案
看到你遇到的问题:按钮默认是GONE状态,首次点击行时按钮能显示但没有平移动画,后续操作动画都正常。我来帮你拆解问题并给出解决方案。
问题根源
核心原因很简单:当View处于GONE状态时,button.getWidth()会返回0!
你第一次点击行的时候,按钮还处于GONE状态,此时调用button.getWidth()拿不到它的真实宽度,得到的是0值。那你创建的显示动画TranslateAnimation(button.getWidth(), 0, 0, 0)就变成了从0平移到0,自然看不到任何动画效果。而当第一次把按钮设为VISIBLE后,按钮完成了布局绘制,后续再调用button.getWidth()就能获取到正确的宽度,所以动画就正常工作了。
解决方案
这里给你三个可行的解决思路,你可以根据自己的场景选择:
方案1:将默认状态改为INVISIBLE(最简单)
把按钮的初始状态从GONE改为INVISIBLE,这样按钮虽然不可见,但依然会参与布局计算,getWidth()能拿到真实的宽度值:
// 初始化时设置按钮状态 button.setVisibility(View.INVISIBLE); // 点击行时显示按钮的代码 button.setVisibility(View.VISIBLE); TranslateAnimation animate = new TranslateAnimation(button.getWidth(), 0, 0, 0); animate.setDuration(500); animate.setFillAfter(true); button.startAnimation(animate);
方案2:监听布局完成事件获取真实宽度(适配GONE场景)
如果必须保持按钮默认GONE的状态,可以通过ViewTreeObserver监听按钮的布局完成事件,等它完成测量后再执行动画:
// 点击行时触发 button.setVisibility(View.VISIBLE); // 监听布局完成,确保能拿到真实宽度 button.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { // 移除监听,避免重复触发 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { button.getViewTreeObserver().removeOnGlobalLayoutListener(this); } else { button.getViewTreeObserver().removeGlobalOnLayoutListener(this); } // 创建并执行动画 TranslateAnimation animate = new TranslateAnimation(button.getWidth(), 0, 0, 0); animate.setDuration(500); animate.setFillAfter(true); button.startAnimation(animate); } });
注意这里要做版本兼容,避免API版本问题。
方案3:使用属性动画替代补间动画(更推荐)
补间动画只是修改View的绘制位置,不会真正改变View的属性;而属性动画会直接操作View的属性,适配性更强,也能避免GONE状态下的宽度问题:
// 显示按钮的代码 button.setVisibility(View.VISIBLE); ObjectAnimator showAnimator = ObjectAnimator.ofFloat(button, "translationX", button.getWidth(), 0); showAnimator.setDuration(500); showAnimator.start(); // 隐藏按钮的代码(动画结束后设置为GONE) ObjectAnimator hideAnimator = ObjectAnimator.ofFloat(button, "translationX", 0, button.getWidth()); hideAnimator.setDuration(500); hideAnimator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) {} @Override public void onAnimationEnd(Animator animation) { button.setVisibility(View.GONE); } @Override public void onAnimationCancel(Animator animation) {} @Override public void onAnimationRepeat(Animator animation) {} }); hideAnimator.start();
这样调整后,首次点击的动画就能正常生效了~
内容的提问来源于stack exchange,提问作者Mohammad Eshraqi
相关产品推荐
相关产品推荐

