Android中视图动画使用率越来越少了,很多大神都使用属性动画了。但个人觉得视图动画比属性动画使用起来更简单,所以能用视图动画实现的就不考虑用属性动画。
今天在项目中使用视图动画时,遇到了几个坑,记录下来,供踩到同样坑的同学参考一下~
一、平移与缩放冲突
使用视图动画,常使用到动画集合AnimationSet,然后在动画集合中添加平移、绽放,旋转等动画。
比如,想实现一个先平移后放大的动画,正常思维下的代码如下:
AnimationSet set = new AnimationSet(true);
// 先平移
int moveX = (large.x + lWidth / 2) - (sLeft + sWidth / 2);
int moveY = (large.y + lHeight / 2) - (sTop + sHeight / 2);
Animation move = new TranslateAnimation(0, moveX, 0, moveY);
move.setInterpolator(new AccelerateDecelerateInterpolator());
move.setDuration(1300);
set.addAnimation(move);
// 再放大
Animation scale = new ScaleAnimation(1.0f, 2.23f, 1.0f, 2.23f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
scale.setInterpolator(new DecelerateInterpolator());
scale.setStartOffset(1300);// 延迟播放
scale.setDuration(1000);
scale.setFillAfter(true);
set.addAnimation(scale);
运行。。。。。
运行效果不一致:实际效果是,先平移,后一边平移一边放大
为什么? 看代码没发现有问题
查了好多资料,才恍然大悟:原来动画集合中平移和缩放会冲突,是因为动画集合中运用了矩阵的知识,想实现先平移后缩放,那么在创建矩阵时,必须先缩放后平移,即动画集合中要先添加缩放后添加平移。
所以实现先平移后放大的代码应该如下:
AnimationSet set = new AnimationSet(true);
// 再放大
Animation scale = new ScaleAnimation(1.0f, 2.23f, 1.0f, 2.23f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
scale.setInterpolator(new DecelerateInterpolator());
scale.setStartOffset(1300);// 延迟播放
scale.setDuration(1000);
scale.setFillAfter(true);
set.addAnimation(scale);
// 先平移
int moveX = (large.x + lWidth / 2) - (sLeft + sWidth / 2);
int moveY = (large.y + lHeight / 2) - (sTop + sHeight / 2);
Animation move = new TranslateAnimation(0, moveX, 0, moveY);
move.setInterpolator(new AccelerateDecelerateInterpolator());
move.setDuration(1300);
set.addAnimation(move);
二、控件操作动画后不能够隐藏(INVISIBLE)
某个控件实现了如下动画:操作渐变,从透明到可见
然后操作隐藏,发现隐藏不了
先上代码吧:
渐变的base_fade_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<alpha
android:duration="1000"
android:fromAlpha="0.0"
android:interpolator="@android:anim/decelerate_interpolator"
android:toAlpha="1.0" />
</set>
渐变动画:
Animation in = AnimationUtils.loadAnimation(this, R.anim.base_fade_in);
in.setFillAfter(true);
mLTipsLayout.startAnimation(in);
隐藏:
mLTipsLayout.setVisibility(View.INVISIBLE);
代码很简单,但实现效果就是隐藏不了,然后一句句注释找原因,原来是这句出了问题:
in.setFillAfter(true);
这句的作用是:让控件定格在动画完成时的状态不变。那么用到上面就是,让控件一直处于可见状态不变。所以后面再操作隐藏就没用了。
当注释上面,OK~~