Android-动画基础合集

来源:互联网 发布:天堂2源码服务端 编辑:程序博客网 时间:2024/05/17 22:16

Android动画

帧动画

逐帧动画是一种常见的动画形式(Frame By Frame),其原理是在“连续的关键帧”中分解动画动作,也就是在时间轴的每帧上逐帧绘制不同的内容,使其连续播放而成动画。 因为逐帧动画的帧序列内容不一样,不但给制作增加了负担而且最终输出的文件量也很大,但它的优势也很明显:逐帧动画具有非常大的灵活性,几乎可以表现任何想表现的内容,而它类似与电影的播放模式,很适合于表演细腻的动画。

开发步骤:

1.在drawable文件夹下定义动画的剧本

<?xml version="1.0" encoding="utf-8"?><animation-list xmlns:android="http://schemas.android.com/apk/res/android"     android:oneshot="true" >    <!-- android:oneshot 动画只演示一次-->    <item android:drawable="@drawable/girl_1" android:duration="200"/>    <item android:drawable="@drawable/girl_2" android:duration="200"/>    <item android:drawable="@drawable/girl_3" android:duration="200"/>    <item android:drawable="@drawable/girl_4" android:duration="200"/>    <item android:drawable="@drawable/girl_5" android:duration="200"/>    <item android:drawable="@drawable/girl_6" android:duration="200"/>    <item android:drawable="@drawable/girl_7" android:duration="200"/>    <item android:drawable="@drawable/girl_8" android:duration="200"/>    <item android:drawable="@drawable/girl_9" android:duration="200"/>    <item android:drawable="@drawable/girl_10" android:duration="200"/>    <item android:drawable="@drawable/girl_11" android:duration="200"/></animation-list>

2.将脚本文件放到图片控件里面

<ImageView    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:src="@drawable/my_animlist"    android:id="@+id/iv"/>

3.在代码中让动画播放起来

@Overridepublic void onClick(View v) {    ImageView iv = (ImageView) findViewById(R.id.iv);    AnimationDrawable drawable= (AnimationDrawable) iv.getDrawable();    drawable.start();}

补间动画

指定两个动画之间起点末点,中间的变化部分由系统来完成。

知识体系:

Animation是所有补间动画的基类,其子类有

  • TranslateAnimation 平移动画
  • ScaleAnimation 缩放动画
  • RotateAnimation 旋转动画
  • AlphaAnimation 透明度动画
  • AnimationSet 动画集动画(多个动画合并在一起)

Animation的基本方法如下,其子类也适用:

  • setDuration(2000) 设置动画时间
  • setFillAfter(true) 设置动画停留在最后一帧
  • setInterpolator(new AccelerateDecelerateInterpolator()); 设置加速器
  • mIv.startAnimation(animation); 控件启动动画 注意 只要是View都能启动动画

TranslateAnimation使用如下

// 定义了两个坐标 开始的坐标 结束的坐标// Type 坐标类型 以自己为基准的坐标 还是以父控件为基准的坐标// RELATIVE_TO_SELF 移动了一个自己的宽度/高度 RELATIVE_TO_PARENT以父控件宽/高作为比例Animation anim = new TranslateAnimation(        Animation.RELATIVE_TO_SELF, 0,        Animation.RELATIVE_TO_PARENT, 0.5f,         Animation.RELATIVE_TO_SELF,0,         Animation.RELATIVE_TO_SELF, 0);anim.setDuration(3000);// 设置动画的时间// 让动画停留在最后一帧anim.setFillAfter(true);// 设置动画的速率 一直加速 一直减速 先加速后减速..... 一般使用Interpolator实现类anim.setInterpolator(new DecelerateInterpolator());// 指定ImageView启动动画 只要控件都可以执行动画mIv.startAnimation(anim);

RotateAnimation使用如下:

// 创建一个旋转的动画 指定旋转中心 指定开始旋转角度0~360 结束的旋转角度0~360Animation anim=new RotateAnimation(180, 360,Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF, 0.5f);anim.setDuration(3000);anim.setFillAfter(true);mIv.startAnimation(anim);

AlphaAnimation使用如下:

Animation anim=new AlphaAnimation(0, 1.0f);anim.setDuration(3000);anim.setFillAfter(true);anim.setRepeatCount(1);//重复一次 1+1=2anim.setRepeatMode(Animation.REVERSE);//效果反过来mIv.startAnimation(anim);

ScaleAnimation使用如下:

// 指定缩放中心 默认在左上角 缩放的比例Animation anim=new ScaleAnimation(1.0f, 0.5f,1.0f, 2.0f,Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF, 0.5f);anim.setDuration(3000);anim.setFillAfter(true);mIv.startAnimation(anim);

AnimationSet使用如下:

// shareInterpolator 共享速率器 如果设置了true 就是以AnimationSet的熟虑器为基准// 多个动画一起启动会相互影响 透明度+移动AnimationSet set = new AnimationSet(true);Animation animRight = new TranslateAnimation(        Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 3f,        Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 3f);animRight.setInterpolator(new AccelerateInterpolator());animRight.setDuration(2000);set.addAnimation(animRight);Animation rotateAnim = new RotateAnimation(0, 720,        Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,        0.5f);rotateAnim.setDuration(1000);rotateAnim.setInterpolator(new DecelerateInterpolator());set.addAnimation(rotateAnim);// set.setDuration(2000);set.setFillAfter(true);set.setInterpolator(new CycleInterpolator(0.5f));mIv.startAnimation(set);

补间动画的XML表示

1.在res/anim下定义xml文件
2.TranslateAnimation的定义如下

<?xml version="1.0" encoding="utf-8"?><translate xmlns:android="http://schemas.android.com/apk/res/android"    android:fromXDelta="0"    android:toXDelta="50%p"    android:fromYDelta="0"    android:toYDelta="0"    android:duration="2000"    android:fillAfter="true"    android:interpolator="@android:anim/accelerate_decelerate_interpolator"  />    <!-- 直接写数据代表移动了确定的像素 比如移动了一个px-->    <!-- 如果设置百分比 那就是本身的宽/高 倍数 -->    <!-- 如果设置百分比p 那就是父控件的宽/高 倍数 -->

3.代码调用如下

Animation anim = AnimationUtils.loadAnimation(this,R.anim.translate_anim);mIv.startAnimation(anim);

按照以上模板,AlphaAnimation的文件定义如下

<?xml version="1.0" encoding="utf-8"?><alpha xmlns:android="http://schemas.android.com/apk/res/android"    android:fromAlpha="0.5"    android:toAlpha="1.0"    android:repeatCount="1"    android:repeatMode="reverse"    android:duration="1000"    android:fillAfter="true"  />

RotateAnimation定义如下

<?xml version="1.0" encoding="utf-8"?><rotate xmlns:android="http://schemas.android.com/apk/res/android"    android:fromDegrees="0"    android:toDegrees="270"    android:pivotX="50%"    android:pivotY="50%"    android:duration="3000"    android:fillAfter="true"    android:interpolator="@android:anim/accelerate_interpolator" />

ScaleAnimation定义如下

<?xml version="1.0" encoding="utf-8"?><scale xmlns:android="http://schemas.android.com/apk/res/android"    android:fromXScale="1.0"    android:toXScale="2.0"    android:fromYScale="1.0"    android:toYScale="2.0"    android:pivotX="50%"    android:pivotY="50%"    android:fillAfter="true"    android:duration="2000" />

AnimationSet的xml即是将多个想要包含的动画作为的子标签。

属性动画合集

Android属性动画是3.0以后才引入的,为什么有了补间动画后还要设计属性动画?这事因为补间动画有一个致命的缺陷,就是它只是改变了View的显示效果而已,而不会真正去改变View的属性。什么意思呢?比如说,现在屏幕的左上角有一个按钮,然后我们通过补间动画将它移动到了屏幕的右下角,现在你可以去尝试点击一下这个按钮,点击事件是绝对不会触发的,因为实际上这个按钮还是停留在屏幕的左上角,只不过补间动画将这个按钮绘制到了屏幕的右下角而已。

ValueAnimator

ValueAnimator是整个属性动画机制当中最核心的一个类,属性动画的运行机制是通过不断地对值进行操作来实现的,它的内部使用一种时间循环的机制来计算值与值之间的动画过渡,我们只需要将初始值和结束值提供给ValueAnimator,并且告诉它动画所需运行的时长,那么ValueAnimator就会自动帮我们完成从初始值平滑地过渡到结束值这样的效果。

final ValueAnimator animator=ValueAnimator.ofFloat(0,1.0f);animator.setDuration(2000);animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {    @Override    public void onAnimationUpdate(ValueAnimator animation) {        Log.i(TAG, "onAnimationUpdate: "+animation.getAnimatedValue());    }});animator.start();

上面的代码用ValueAnimator的ofFloat()方法就可以构建出一个ValueAnimator的实例,ofFloat()方法当中允许传入多个float类型的参数,这里传入0和1就表示将值从0平滑过渡到1,然后调用ValueAnimator的setDuration()方法来设置动画运行的时长,最后调用start()方法启动动画。

可是这只是一个将值从0过渡到1的动画,又看不到任何界面效果,我们怎样才能知道这个动画是不是已经真正运行了呢?这就需要借助监听器来实现,上面的监听器会打印在此期间0~1之间的数据变化 我们可以通过该变化来维护我们的View.

ObjectAnimator

相比于ValueAnimator,ObjectAnimator可能才是我们最常接触到的类,因为ObjectAnimator直接对任意对象的任意属性进行动画操作的,比如说View的alpha属性。

启动一个透明度动画:

ObjectAnimator objAnimator=ObjectAnimator.ofFloat(mTextView,"alpha",1.0f,0,1.0f);objAnimator.setDuration(3000);objAnimator.start();

启动一个旋转动画:

ObjectAnimator rotateAnimator = ObjectAnimator.ofFloat(mTextView, "rotation", 0, 360.0f,0);rotateAnimator.setDuration(2000);rotateAnimator.start();

启动一个平移动画:

float translationX = mTextView.getTranslationX();ObjectAnimator translationAnimator = ObjectAnimator.ofFloat(mTextView, "translationX", translationX, -500, translationX);translationAnimator.setDuration(3000);translationAnimator.start();

启动一个缩放动画:

ObjectAnimator scaleAnimator = ObjectAnimator.ofFloat(mTextView, "scaleY", 1.0f, 3.0f, 2.0f);scaleAnimator.setDuration(3000);scaleAnimator.start();

除了上面的几种动画 平时我们也可能将多个动画集合在一起播放。这里涉及到一个AnimatorSet类。其提供了如下方法:

  • after(Animator anim) 将现有动画插入到传入的动画之后执行
  • after(long delay) 将现有动画延迟指定毫秒后执行
  • before(Animator anim) 将现有动画插入到传入的动画之前执行
  • with(Animator anim) 将现有动画和传入的动画同时执行

以下就是展示的示例

ObjectAnimator rotate = ObjectAnimator.ofFloat(mTextView, "rotation", 0, 360.0f,0);float textViewX = mTextView.getTranslationX();ObjectAnimator translation = ObjectAnimator.ofFloat(      mTextView, "translationX", textViewX, -500, textViewX);ObjectAnimator scale=ObjectAnimator.ofFloat(mTextView,"scaleY",1.0f,3.0f,2.0f);AnimatorSet set=new AnimatorSet();set.play(translation).after(rotate).with(scale);set.setDuration(3000);set.start();

有时候我们想知道动画变化的过程中是怎么样的 可以给动画/动画集一个监听器,代码如下:

scaleAnimator = ObjectAnimator.ofFloat(mTextView, "scaleY", 1.0f, 3.0f, 2.0f);scaleAnimator.addListener(new Animator.AnimatorListener() {   @Override   public void onAnimationStart(Animator animation) {   }   @Override   public void onAnimationEnd(Animator animation) {   }   @Override   public void onAnimationCancel(Animator animation) {   }   @Override   public void onAnimationRepeat(Animator animation) {   }});

上面的监听器需要实现四个方法 太麻烦了 我们可以使用其子类AnimatorListenerAdapter

scaleAnimator = ObjectAnimator.ofFloat(mTextView, "scaleY", 1.0f, 3.0f, 2.0f);scaleAnimator.addListener(new AnimatorListenerAdapter() {    @Override    public void onAnimationStart(Animator animation) {        Log.i(TAG, "onAnimationStart: " + animation.getDuration());    }});

除了这些 我们从补间动画学习到,动画既可以通过代码创建也可以通过xml创建,既然这样,接下来我们在res下创建一个animator文件夹,并定义一个文件,该文件有几种最主要的标签:

  • 对应代码中的ValueAnimator
  • 对应代码中的ObjectAnimator
  • 对应代码中的AnimatorSet

我们定义的文件如下:

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android">    <objectAnimator        android:propertyName="scaleX"        android:duration="3000"        android:valueFrom="1.0"        android:valueTo="4.0"        android:valueType="floatType" />    <objectAnimator        android:propertyName="scaleY"        android:duration="3000"        android:valueFrom="1.0"        android:valueTo="4.0"        android:valueType="floatType" /></set>

那么如何引用该文件呢,接下来看看代码是怎么做的?

Animator animatorSet = AnimatorInflater.loadAnimator(this, R.animator.my_animset);animatorSet.setTarget(mTextView);animatorSet.start();
0 0
原创粉丝点击