setTranslationY()与translationYBy()的区别及动画异常问题咨询
问题解析:为什么
translationYBy初始移出无效,以及setTranslationY与translationYBy的区别 嘿,这个问题其实核心在于ViewPropertyAnimator的动画是异步执行的,我来给你拆解清楚:
为什么无效代码没效果?
你写的这段无效代码:
imageView.animate().translationYBy(-2000); imageView.setImageResource(R.drawable.red); imageView.animate().translationYBy(2000).setDuration(300);
问题出在imageView.animate().translationYBy(-2000)这一行——调用这个方法后,动画并不会立刻把ImageView移出去,而是会把这个动画任务放到UI线程的消息队列里,等待后续执行。
而你紧接着就执行了设置图片和第二个translationYBy(2000)动画,这时候第一个动画还没来得及运行,第二个动画就直接覆盖了它(ViewPropertyAnimator会取消未执行的前序动画)。最终只有第二个动画执行,但此时ImageView还在原来的位置,translationYBy(2000)反而会把它往下移2000,自然看不到你想要的“从顶部滑入”效果。
而有效代码里的imageView.setTranslationY(-2000)是同步操作,调用后立刻修改了ImageView的translationY属性,把它直接移到屏幕外,之后的动画是从这个位置往回移,所以能正常看到滑入效果。
setTranslationY() 和 translationYBy() 的核心区别
我给你把两者的差异理得明明白白:
setTranslationY(float y):这是View类自带的属性设置方法,属于同步操作,调用后立刻修改View的translationY属性的绝对值,直接改变View的位置,没有动画过渡。比如setTranslationY(-2000)就是把View的Y轴偏移量直接设为-2000,瞬间到位。translationYBy(float deltaY):这是ViewPropertyAnimator提供的动画方法,属于异步动画操作,它会让View的translationY属性在当前值的基础上增加deltaY,这个过程是通过动画逐步完成的,不会立刻改变属性值。而且如果连续调用多个这类动画,未执行的前序动画会被后序动画覆盖。
如何修正无效代码?
如果你想用translationYBy实现同样的效果,可以利用动画的结束回调,等第一个“移出”动画完成后再执行后续操作:
// 先执行瞬间移出的动画(duration设为0) imageView.animate() .translationYBy(-2000) .setDuration(0) .withEndAction(new Runnable() { @Override public void run() { // 移出完成后设置图片,再执行滑入动画 imageView.setImageResource(R.drawable.red); imageView.animate() .translationYBy(2000) .setDuration(300); } });
这样就能保证动画的执行顺序,达到和有效代码一样的效果。
内容的提问来源于stack exchange,提问作者Rishabh Jain
相关产品推荐
相关产品推荐

