Android三大动画详解
1、Frame Animation(逐帧动画)
逐帧播放事先定义好的图片,给人在视觉上带来动画效果,类似胶片电影播放原理。
1-1、快速入门
1-1-1、准备几张图片,放到图片资源文件下。
1-1-2、创建Animation-list帧布局文件,放在res/drawable目录下
<?xml version="1.0" encoding="utf-8"?><animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> <item android:drawable="@mipmap/nv1" android:duration="500" /> <item android:drawable="@mipmap/nv2" android:duration="500" /> <item android:drawable="@mipmap/nv3" android:duration="500" /> <item android:drawable="@mipmap/nv4" android:duration="500" />animation-list>
属性说明:
(1) android:oneshot 设置是否仅播放一次
(2) android:drawable 设置每一帧图片
(3) android:duration 设置图片间切换间隔
1-1-3、布局文件代码如下:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/btn_start" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="开始" /> <Button android:id="@+id/btn_stop" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="停止" /> <Button android:id="@+id/btn_start2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="倒序" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <ImageView android:id="@+id/imageViewId" android:layout_width="60dp" android:layout_height="60dp" android:layout_marginTop="100dp" android:layout_gravity="center" android:layout_centerInParent="true"/> LinearLayout>LinearLayout>
1-1-4、FrameAnimationActivity代码如下:
public class FrameAnimationActivity extends AppCompatActivity { private Button btn_start,btn_start2; private Button btn_stop; private ImageView imageView = null; private AnimationDrawable animationDrawable = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_frameanimation); btn_stop = (Button) findViewById(R.id.btn_stop); btn_start = (Button) findViewById(R.id.btn_start); btn_start2 = (Button) findViewById(R.id.btn_start2); imageView = (ImageView) findViewById(R.id.imageViewId); btn_start.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { imageView.setBackgroundResource(R.drawable.anim_nv); animationDrawable = (AnimationDrawable) imageView.getBackground(); animationDrawable.start(); } }); btn_start2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { imageView.setBackgroundResource(R.drawable.anim_nv2); animationDrawable = (AnimationDrawable) imageView.getBackground(); animationDrawable.start(); } }); btn_stop.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { animationDrawable.stop(); } }); }}
看见没,其实只要几个步骤就能轻松实现逐帧动画
第一步将Animation-list帧布局文件资源设置为ImageView的背景
imageView.setBackgroundResource(R.drawable.anim_nv);
第二步获取ImagView的背景并将其转换成AnimationDrawable
animationDrawable = (AnimationDrawable) imageView.getBackground();
第三步开始播放动画
animationDrawable.start();
上面的动画文件是通过xml文件来配置的,我们也可以通过在java代码中创建AnimationDrawable对象,然后通过addFrame(Drawable frame, int duration)方法向动画添加帧,然后start()。
1-1-5、倒序播放Animation-list帧布局文件
<?xml version="1.0" encoding="utf-8"?><animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> <item android:drawable="@mipmap/nv4" android:duration="500" /> <item android:drawable="@mipmap/nv3" android:duration="500" /> <item android:drawable="@mipmap/nv2" android:duration="500" /> <item android:drawable="@mipmap/nv1" android:duration="500" />animation-list>
2、Tween Animation(补间动画)
补间动画就是我们只需指定开始、结束的“关键帧“,而变化中的其他帧由系统来计算,不必自己一帧帧的去定义。
2-1、补间动画种类
抽象类Animation是一个实现androidUI界面动画效果的API,Animation是补间动画的基类,它的直接子类AlphaAnimation, RotateAnimation, ScaleAnimation, TranslateAnimation,AnimationSet,提供了一系列的动画效果,可以进行淡入淡出、旋转、缩放、动画集等,这些效果可以应用在绝大多数的控件中。
2-1-1、AlphaAnimation(淡入淡出动画)
a、使用xml资源文件方式配置动画
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator"> <alpha android:duration="500" android:fromAlpha="1.0" android:startOffset="500" android:toAlpha="0.0" />set>
把动画设置给某个组件
//使用AnimationUtils装载动画设置文件 Animation animation = AnimationUtils.loadAnimation(TweenAnimationActivity.this, R.anim.alpha); imageView.startAnimation(animation);
b.使用代码的方式完成AlphaAnimation动画
//创建一个AnimationSet对象 AnimationSet animationSet = new AnimationSet(true); //创建一个AlphaAnimation对象 AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0); //设置动画执行的时间(单位:毫秒) alphaAnimation.setDuration(1000); //将AlphaAnimation对象添加到AnimationSet当中 animationSet.addAnimation(alphaAnimation); //使用ImageView的startAnimation方法开始执行动画 imageView.startAnimation(animationSet);
2-1-2、RotateAnimation(旋转的动画)
a、使用xml资源文件方式配置动画
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/bounce_interpolator"> <rotate android:fromDegrees="0" android:toDegrees="360" android:pivotX="50%" android:pivotY="50%" android:duration="5000" />set>
把动画设置给某个组件
Animation animation = AnimationUtils.loadAnimation(TweenAnimationActivity.this, R.anim.rotate); animation.setInterpolator(new AccelerateInterpolator()); imageView.startAnimation(animation);
b.使用代码的方式完成RotateAnimation动画
AnimationSet animationSet = new AnimationSet(true); RotateAnimation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_PARENT, 1f, Animation.RELATIVE_TO_PARENT, 0f); rotateAnimation.setDuration(5000); animationSet.addAnimation(rotateAnimation); imageView.startAnimation(animationSet);
2-1-3、ScaleAnimation(缩放动画)
a、使用xml资源文件方式配置动画
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator"> <scale android:fromXScale="1.0" android:toXScale="0.0" android:fromYScale="1.0" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:duration="2000" />set>
把动画设置给某个组件
Animation animation = AnimationUtils.loadAnimation(TweenAnimationActivity.this, R.anim.sacle); imageView.startAnimation(animation);
b.使用代码的方式完成ScaleAnimation动画
AnimationSet animationSet = new AnimationSet(true); ScaleAnimation scaleAnimation = new ScaleAnimation(1, 0.1f, 1, 0.1f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); animationSet.addAnimation(scaleAnimation); animationSet.setStartOffset(1000); animationSet.setFillAfter(true); animationSet.setFillBefore(false); animationSet.setDuration(2000); imageView.startAnimation(animationSet);
2-1-4、TranslateAnimation(位移动画)
a、使用xml资源文件方式配置动画
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator"> <translate android:fromXDelta="50%" android:toXDelta="100%" android:fromYDelta="0%" android:toYDelta="100%" android:duration="2000" />set>
把动画设置给某个组件
Animation animation = (Animation) AnimationUtils.loadAnimation(TweenAnimationActivity.this, R.anim.translate); imageView.startAnimation(animation);
b.使用代码的方式完成TranslateAnimation动画
AnimationSet animationSet = new AnimationSet(true); TranslateAnimation translateAnimation = new TranslateAnimation( Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 1.0f); translateAnimation.setDuration(1000); animationSet.addAnimation(translateAnimation); imageView.startAnimation(animationSet);
2-1-5、动画插入器,Android自带的几种动画插入器:
AccelerateDecelerateInterolator 先加速后减速,开始结束时慢,中间加速
AccelerateInterpolator 加速,开始时慢中间加速
DecelerateInterpolator 减速,开始时快然后减速
AnticipateInterpolator 反向 ,先向相反方向改变一段再加速播放
AnticipateOvershootInterpolator 反向加超越,先向相反方向改变,再加速播放,会超出目的值然后缓慢移动至目的值
BounceInterpolator 跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100
CycleIinterpolator 循环,动画循环一定次数,值的改变为一正弦函数:Math.sin(2 mCycles Math.PI * input)
LinearInterpolator 线性,线性均匀改变
OvershottInterpolator 超越,最后超出目的值然后缓慢改变到目的值
TimeInterpolator 一个接口,允许你自定义interpolator,以上几个都是实现了这个接口
插值器的使用方法:
3、Property Animation(属性动画)
属性动画,这个是在Android 3.0中才引进的,它可以直接更改我们对象的属性。在上面提到的Tween Animation中,只是更改View的绘画效果而View的真实属性是不改变的。假设你用Tween动画将一个Button从左边移到右边,无论你怎么点击移动后的Button,他都没有反应。而当你点击移动前Button的位置时才有反应,因为Button的位置属性木有改变。而Property Animation则可以直接改变View对象的属性值,这样可以让我们少做一些处理工作,提高效率与代码的可读性。
Property Animation参数地址:http://blog.csdn.net/lmj623565791/article/details/38067475/
三种动画对比
(1)Frame Animation(帧动画)主要用于播放一帧帧准备好的图片,类似GIF图片,优点是使用简单方便、缺点是需要事先准备好每一帧图片;
(2)Tween Animation(补间动画)仅需定义开始与结束的关键帧,而变化的中间帧由系统补上,优点是不用准备每一帧,缺点是只改变了对象绘制,而没有改变View本身属性。因此如果改变了按钮的位置,还是需要点击原来按钮所在位置才有效。
(3)Property Animation(属性动画)是3.0后推出的动画,优点是使用简单、降低实现的复杂度、直接更改对象的属性、几乎可适用于任何对象而仅非View类,缺点是需要3.0以上的API支持,限制较大!但是目前国外有个开源库,可以提供低版本支持!