第一讲,我们主要讲的是android-tween动画的理论知识,其中涉及到六个核心类,两个核心接口,这些内容是撑起android-tween动画的基石;有了理论基础知识之后,我们来做个简单的动画,这个动画只是为了展示下android-tween动画怎么写,完全不考虑美观,交互,不喜勿喷。没有动画基础的可以先看下我写的第一讲,有动画基础的各位看官,可以直接跳过,来看下面这个丑陋的demo。上文说过,动画的实现需要有两种方式,一种是通过XML+java代码实现,一种是直接动态撸代码;下面我通过两种方式来实现下面这个动画。
图 1
一、XML+JAVA实现
xml内容如下:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:interpolator="@android:interpolator/accelerate_quint"
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="0"
android:toYDelta="300"
android:duration="2000"/>
<set
android:duration="3000"
android:startOffset="2000"
>
<rotate
android:fromDegrees="0"
android:toDegrees="360"
android:pivotY="50%"
android:pivotX="50%"
/>
<scale
android:fromXScale="1.0"
android:fromYScale="1.0"
android:toXScale="1.5"
android:toYScale="1.5"
android:pivotX="50%"
android:pivotY="50%"
/>
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.4"
/>
</set>
</set>
java代码实现:(只给出了核心内容)
private ImageView imageView;
private Animation animation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imageView = (ImageView) findViewById(R.id.iv);
btnStartAnim = (Button) findViewById(R.id.btn_start_anim);
btnEndAnim = (Button) findViewById(R.id.btn_end_anim);
<strong>animation = AnimationUtils.loadAnimation(this,R.anim.anim_demo);</strong>
btnStartAnim.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
<strong>imageView.startAnimation(animation);</strong>
}
});
}
其中涉及到的ImageView的drawable资源,及layout布局文件都很简单,这里就不粘贴;通过xml+java的方式来实现动画,其实核心内容是xml中的属性设置,java代码很容易,核心代码就上面加粗的两行代码;
xml的内容也不难,里面没什么特别的属性,都是很常见的,只是一次为了把四种动画都显示出来,和暴露问题,我就一次把能用到内容和易出现疑惑的内容都加在这个一个demo里面了;看不懂的读者可以再看看第一讲的属性介绍,再加上效果图,对比着看,在本文的结尾我会简单讲讲这个动画;接下来,我用java代码动态撸这个动画;
二、java代码实现;
java代码实现相比xml实现墨迹点,但是有很多需求,需要我们在代码中动态实现,所以我们还是需要会的,虽然墨迹,但是不难。
解析过JSON内容的小伙伴都知道,JSON内容的解析是一层层的去“扒皮”,最后再由内而外的解析成Object对象,用代码写动画也这样,先写里面最基础的动画,最后再一层层放到容器里面,形成AnimaitonSet动画集,交给view去处理。废话不多说了,直接上代码:
AlphaAnimation alpha = new AlphaAnimation(1.0f,0.4f);
ScaleAnimation scale = new ScaleAnimation(1.0f,1.5f,1.0f,1.5f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
RotateAnimation rotate = new RotateAnimation(0.0f,360.0f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
AnimationSet animatorSet1 = new AnimationSet(true);
animatorSet1.setDuration(3000);
animatorSet1.setStartOffset(2000);
animatorSet1.addAnimation(alpha);
animatorSet1.addAnimation(scale);
animatorSet1.addAnimation(rotate);
TranslateAnimation translate = new TranslateAnimation(0.0f,0.0f,0.0f,300.0f);
translate.setDuration(2000);
translate.setInterpolator(new AccelerateInterpolator());
final AnimationSet animationSet = new AnimationSet(false);
animationSet.addAnimation(translate);
animationSet.addAnimation(animatorSet1);
imageView.startAnimation(animationSet);
btnStartAnim.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
imageView.startAnimation(animationSet);
}
});
上面是通过java代码动态实现的;通过代码实现比xml实现冗余的多,而且可读性差,复用性差,所以,除非特殊情况,建议tween动画都用xml来实现吧。
具体的代码,我就不一行一行的解释了,很简单,参照着第一讲的内容和上面的动画效果也很好理解。下面咱们分析下上面动画存在的坑。
三、动画分析:
动画单独去使用的相对较少,一般会组合使用。上面我用了四种动画,并且按照动画同时执行和先后执行来给四种动画分成两个动画集。同时执行在AnimationSet中设置duration就完了,先后执行的话,设置个startOffset就行了,也很容易。但是在动画集执行的过程中发现了个难点,困难的地方地方在于在xml中如何去写旋转动画和缩放动画的轴心。在旋转的过程中我本来想做成下面这个动画的样子的,但是却做成了图1的样子。(注:下面的动画是我用属性动画写的)
图 2
到目前为止,我依然没法用tween动画作出图2这个动画的效果,在我看来tween动画是“死”的,几乎没有扩展性,它是按照你预先设定好的路径去走,轴心没法动态变化,直到动画结束恢复原样。在动画执行的过程中是没办法去动态改变动画的参数和view的属性,所以在我看来,用tween动画是做不出来图2的效果的,如果有大牛能用tween动画做出图2的效果一定要在博客下方留言,小弟感谢万分。
好了,在这里总结下我遇到的写tween动画过程中的坑和经验:
1、属性动画是先去规划好动画路径(无论是xml+java的形式,还是纯java的写法,都是在规划路径),然后再按照动画的路径去执行,中间不能改变动画的任何设置,除非clearAnimation;
2、在xml中写动画中参数值的时候,如果单位的类型是ABSOLUTE 时,一定要注意,默认单位是px,而不是dp,而且是不用写单位的,直接写数值就完了。在layout布局中是必须要写单位的哦,不写编译不过;所以在写死数值的时候,要注意单位的换算,注意各种分辨率的适配。
3、当参数单位的类型为RELATIVE_TO_SELF、RELATIVE_TO_PARENT 的,数值为50%,50%p这样的写法的时候,计算出来的值,是依照你当前view和ViewGroup的宽高来计算的,而不是动态计算的,所以当我设置rotate的pivoX=50%,pivoY=50%的时候,旋转的中心是图1中蓝色的小点,而不是看到的矩形的中心。
4、由第三条经验得到:做缩放、旋转的动画,最好呆在那做,别移动,否则效果一定超出你的预期,因为做动画的时候不会去动态算轴点了。
5、对控件做动画,如果控件有点击事件,而且点击事件效果不同的话,切记在onAnimtionStarted的时候让控件无法点击,在onAnimationEnd的时候,恢复点击事件;
好了,本节内容到此为止,以上内容纯属本人经验之谈,及个人理解,鉴于本人水平有限,表达能力有限,难免有的地方描述错,或者理解错,有大牛看到还望指正、拍砖。