红色部分为本身的实践理解app
如何实现将View向上平移自身高度一半的距离?框架
TranslateAnimation translate = new TranslateAnimation(学习
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0, 动画
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0.5f);this
mView.startAnimation(translate);spa
问题:当动画结束后,View会跳回到原始位置。.net
改进:orm
AnimationSet set = new AnimationSet(true);blog
TranslateAnimation translate = new TranslateAnimation(事件
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0,
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0.5f);
set.addAnimation(translate);
set.setFillAfter(true);//这个必须设置在AnimationSet上面,设置在Animation上不起做用,网上不少写法实际上是错误的
mView.startAnimation(set);
setFillAfter文档说明:
If fillAfter is true, the transformation that this animation performed
will persist when it is finished. Defaults to false if not set.
设为true以后,界面会停留在动画播放完时的界面。
问题:动画结束后界面显示正确,可是View上各控件的实际位置和看上去的位置不对应,
实际位置还在View的原始位置,所以button的点击位置会有问题,和看见的位置有误差。
好比你把一个button用动画从最左面移到最右面,虽然UI上显示button到了最右面,但其实你在右面点button并不会触发click事件,只有点最左面才会触发
正确方法:
AnimationSet set = new AnimationSet(true);
TranslateAnimation translate = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0,
Animation.RELATIVE_TO_SELF, 0.5, Animation.RELATIVE_TO_SELF, 0);
set.addAnimation(translate);
set.setFillAfter(true);
mView.offsetTopAndBottom(-mView.getHeight() / 2);
mView.startAnimation(set);
先将View向上平移自身高度一半的距离,而后播放动画,从最初位置一直向上移动目标位置。
初看感受是在原始位置下1/2处开始动画往上,最后到原始位置,其实不是这样的,正如总结里说的要倒过来看,是先把view的位置真正移上去自身一半高度,而后从移上去一半高度的位置算那个动画初始位置,其实就是最初位置开始动画,网上移一半高度,最后其实就是mView.offsetTopAndBottom(-mView.getHeight() / 2)的位置。
setFillBefore文档说明:
If fillBefore is true, this animation will apply its transformation
before the start time of the animation. Defaults to true if
setFillEnabled(boolean) is not set to true.
对TranslateAnimation,setFillBefore默认为true,也就是说在动画开始前,先将transformation
apply到View,这也就是为何offsetTopAndBottom()后,View依然从原始位置开始运动。
若是setFillBefore设为false,动画播放时会有一个跳动,能够看到View从目标位置跳到原始位置。
总结:
使用Animation、AnimationSet框架实现的动画效果,必须先将View放置到最终的目标位置,
而后倒过来,播放从原始位置到目标位置的动画。
若是动画结束后把view设成View.Gone的话,这段动画直接放在onCreate()中的话,动画不会启动,所以作demo的时候总发现怎么不触发,放到view的Click事件里触发就没问题。包括-mView.getHeight() / 2在onCreate里由于onMeasure等方法由于没有执行完成,因此getHeight()是不正确的。所以若是学习的时候,只是作小demo看结果的话最好不要直接放在onCreate里(具体缘由和解决方案看http://blog.csdn.net/johnny901114/article/details/7839512)