Android应用开发Android动画机制及其使用
白羽 2018-11-14 来源 :网络 阅读 158 评论 0

摘要:本文将带你了解Android应用开发Android动画机制及其使用,希望本文对大家学Android有所帮助。

    本文将带你了解Android应用开发Android动画机制及其使用,希望本文对大家学Android有所帮助。


<

作为交互的一部分,开发Android应用的时候时常会用到动画,这样可以使应用看起来不那么死板。某些较为特定的点击可以使用有趣的动画引起注意,进而可以获取更多的点击量。随着Android系统的不断完善,其动画机制也不断地改进,如早期的帧动画和补间动画,3.0之后加入属性动画,以及之后5.x加入的SVG矢量动画等。以下讲一些较为常用的动画实现方式,即帧动画、补间动画和属性动画。
逐帧动画(Frame Animation)
逐帧动画也称之为Drawable Animation,是通过一系列的图片按顺序播放使其连成动画,这里每一帧都有对应的图片。例如我需要将名字为“droidman01”到“droidman16”的16张图片连成帧动画动画,那么实现方式如下
XML中:
将每一帧的图片放入res的drawable中然后再res的anim中(没有则新建一个Directory命名为anim)或是Android Studio的drawable中新建一个动画XML文件,使用标签来定义各个帧动图片的顺序,通过标签来排列。
<!--xml version="1.0" encoding="utf-8"-->     <item android:drawable="@drawable/droidman01" android:duration="150">    <item android:drawable="@drawable/droidman02" android:duration="150">...</item></item></animation-list>

imageView.setImageResource(R.drawable.frameanim);AnimationDrawable animationDrawable = (AnimationDrawable) imageView.getDrawable();animationDrawable.start();

这里的oneshot表示是否只执行一次,为false则执行一次就结束动画,为true当然就是循环播放。android:duration则是该帧图片播放的持续时间。
java代码中:
AnimationDrawable animationDrawable = new AnimationDrawable();for (int i = 1;i<16;i++){    int id;    if (i<10){        id = getResources().getIdentifier("droidman0"+i,"drawable",getPackageName());    }else{        id = getResources().getIdentifier("droidman"+i,"drawable",getPackageName());    }    Drawable drawable = getResources().getDrawable(id);    animationDrawable.addFrame(drawable,150);}imageView.setImageDrawable(animationDrawable);animationDrawable.setOneShot(false);animationDrawable.start();

在这里会看到一个方法getIdentifier(),这个方法是用来获取资源id的。第一个参数是资源名,第二个参数是资源类型可以为null,第三个参数是包名,也可以为空。这个方法对于获取资源名称类似的很有用,很方便。这里通过addFrame方法传入每帧的图片,并设置播放时间,同样代码中可通过setOneShot方法设置是否循环播放,最后通过start()方法开始播放动画。除此之外AnimationDrawable还提供其他方法如:
stop():停止播放动画
isRunning():放回boolean类型表示动画是否正在播放中
run():继续从下一帧开始播放
getNumberOfFrames():获取总帧数
getFrame(int index):获取指定帧图片
getDuration(int i):获取指定帧播放时间
isOneShot():是否是一次播放
上面动画的效果:

补间动画(Twwen Animation)
补间动画无需定义每一帧,只需定义开始和结束的关键两帧,中间的变化可设置插值器(Interpolator)来平滑过渡。补间动画提供了四个基本类型的动画:AlphaAnimation、RotateAnimation、TranslateAnimation和ScaleAnimation。其实这些动画使用起来相对不难,只要知道各个参数的含义即可。一下就一一说明。
AlphaAnimation
// 参数分别为开始和结束时的透明度,参数的取值区间[0,1]的float类型,即全透明到完全不透明。AlphaAnimation alphaAnimation = new AlphaAnimation(0,1);

RotateAnimation
// 两参数分别为动画开始时的旋转角度和动画结束时的旋转角度,以点(0,0)为中心旋转RotateAnimation rotateAnimation1 = new RotateAnimation(0,360);// 旋转角度从0度到360度,旋转中心为点(100,100)RotateAnimation rotateAnimation2 = new RotateAnimation(0,360,100,100);// 旋转角度从0到360度。X轴方向上的旋转参考类型,相对参考类型的X坐标位置,Y轴方向上旋转的参考类型,相对参考类型的Y坐标位置,// 此处参考类型有RotateAnimation.RELATIVE_TO_SELF自身,RotateAnimation.ABSOLUTE绝对位置,RotateAnimation.RELATIVE_TO_PARENT父控件,// 如该写法为以自身的中心位置旋转RotateAnimation rotateAnimation3 = new RotateAnimation(0,360,RotateAnimation.RELATIVE_TO_SELF,0.5F,RotateAnimation.RELATIVE_TO_SELF,0.5F);

TranslateAnimation
// 参数分别为动画开始X坐标,动画结束X坐标,动画开始Y坐标,动画结束X坐标。即动画效果是从(0,0)平移到(200,300)位置TranslateAnimation translateAnimation1 = new TranslateAnimation(0,200,0,300);// 和旋转的一样,有着参考类型,该效果为从该控件的(0,0)开始到控件宽高的2倍位置TranslateAnimation translateAnimation2 = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_SELF,0F,TranslateAnimation.RELATIVE_TO_SELF,0F,    TranslateAnimation.RELATIVE_TO_SELF,2F,TranslateAnimation.RELATIVE_TO_SELF,2F);

ScaleAnimation
// 参数分别为动画开始时的X轴坐标伸缩尺寸,动画结束时X轴伸缩尺寸,动画开始时Y轴伸缩尺寸,动画结束时Y轴伸缩尺寸。其中尺寸数值为该空间原始大小的倍数。// 该效果为以点(0,0)开始向外放大2倍ScaleAnimation scaleAnimation1 = new ScaleAnimation(0f,2f,0f,2f);// 前四个参数与上一样,后两个为缩放中心ScaleAnimation scaleAnimation2 = new ScaleAnimation(0f,2f,0f,2f,100,200);// 前四个参数与上一样,后四个为参考类型和参考相对位置,如此效果为以自身中心X,Y轴都伸展为原来的2倍ScaleAnimation scaleAnimation3 = new ScaleAnimation(0f,2f,0f,2f,ScaleAnimation.RELATIVE_TO_SELF,0.5F,ScaleAnimation.RELATIVE_TO_SELF,0.5F);

使用时只需设置动画时间即可开启动画,以透明动画为例,其他用法类似
//动画持续时间alphaAnimation.setDuration(1000);//动画结束时保留状态alphaAnimation.setFillAfter(true);//设置插值器alphaAnimation.setInterpolator(new LinearInterpolator();//开启动画imageView.startAnimation(alphaAnimation);

动画叠加AnimationSet
AnimationSet animationSet = new AnimationSet(true);animationSet.setDuration(2000);animationSet.addAnimation(alphaAnimation);animationSet.addAnimation(rotateAnimation1);animationSet.addAnimation(translateAnimation1);animationSet.addAnimation(scaleAnimation1);imageView.startAnimation(animationSet);

通过AnimationSet的addAnimation方法可将各动画添加进来,然后设置时间即可。
动画监听
animation.setAnimationListener(new Animation.AnimationListener() {    @Override    public void onAnimationStart(Animation animation) {        // 动画开始时    }     @Override    public void onAnimationEnd(Animation animation) {        // 动画结束时    }     @Override    public void onAnimationRepeat(Animation animation) {        // 重复动画时    }});

我们常常会在动画执行的开始或者结束时做一些相应的操作,此时就会需要监听动画的执行过程。如一个动画之后执行另一个动画等。
属性动画(Property Animation)
Android 3.0之后引进了属性动画,相较于之前的动画,属性动画真实改变了View的属性,而之前的那两种动画则只是视图上的改变,其触发位置仍旧没有变化,因此属性动画更适合做一些需要交互较强的动画。
ObjectAnimator
属性动画常用到的一个类就是ObjectAnimator,它是属性动画中最重要的一个执行类,继承自属性动画中最重要的类ValueAnimator。ObjectAnimator使用起来也相对较方便,只要记得第二个参数所要执行的动画即可,因为这里所填的是第一个参数对象的属性,且这个属性必须有get、set方法。我们以一个简单的用法来说明
ObjectAnimator objectAnimator =ObjectAnimator.ofFloat(imageView,"translationX",-300,300);objectAnimator.setDuration(2000);// 设置播放次数。如果为ValueAnimator.INFINITE表示无限播放下去objectAnimator.setRepeatCount(ValueAnimator.INFINITE);// 设置播放重复模式。RESTART表示重新开始动画,REVERSE表示动画反过来播放。objectAnimator.setRepeatMode(ValueAnimator.REVERSE);objectAnimator.start();

通过ObjectAnimator的工厂方法创建对象,其中第一个参数是要操作的View,第二个参数是要操作的属性,第三个参数是对应的属性变化,其是一个可变数组,即后面可继续添加参数,如这个效果就是将imageView控件在X轴方向的位移。第三个参数及其之后的参数为关键转折点。重点说下第二个参数,我们对View的动画操作常用的有(即第二个参数的值):
pivotX和pivotY:设置View的支点位置,默认为View的中心点
translationX和translationY:View的X轴和Y轴的偏移量,或者说位移距离。
rotation、rotationX和rotationY:View围绕支点,分别以Z轴、X轴和Y轴旋转,其中Z轴垂直屏幕。
scaleX和scaleY:View以支点做缩放。
x和y:直接设置View的位置,相当于原位置移动x和y距离。
alpha:设置View的透明度,1不透明,0全透明。
那么之前所说的set和get和这些值有什么关系呢?我们会有这些值,是因为内部通过java反射机制来调用set函数修改对象的属性值,我们打开源码ImageView继承View,而View中有一系列的函数,即方法。我们可以发现这些可以改变View属性的方法,如setTranslationX/getTranslationX、setRotationX/getRotationX等,这才使得属性动画能够找到这些方法并对其属性值做更改。
PropertyValuesHolder
PropertyValuesHolder使用起来和ObjectAnimator一样,只是它可以通过ObjectAnimator的ofPropertyValuesHolder方法将各个效果叠加起来,和AnimationSet类似。其使用方法如下,效果是在移动同时进行缩放操作。
PropertyValuesHolder pvh1 = PropertyValuesHolder.ofFloat("translationX",200f);PropertyValuesHolder pvh2 = PropertyValuesHolder.ofFloat("scaleX",1f,0f,1f);PropertyValuesHolder pvh3 = PropertyValuesHolder.ofFloat("scaleY",1f,0f,1f);ObjectAnimator.ofPropertyValuesHolder(imageView,pvh1,pvh2,pvh3).setDuration(2000).start();

ValueAnimator
ValueAnimator是属性动画中最重要的一个类,继承自Animator。它定义了属性动画中大部分的功能,如计算各帧的属性值、处理更新事件、根据属性值得类型知道操作的属性对象而做相应的计算规则的控制。也就是说ValueAnimator其实本身不负责动画的执行,更重要的是动画执行过程中数据的获取。可以根据需要设置动画持续的时间、插值方式、重复次数等,然后启动动画。使用时一般需要注册AnimatorUpdateListener监听器。然后再监听器中获取实时数值,之后将得到的数值设置到需要的地方。用法大致如下:
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0,100);valueAnimator.setTarget(imageView);valueAnimator.setDuration(2000);valueAnimator.start();valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {    @Override    public void onAnimationUpdate(ValueAnimator animation) {        Float value = (Float) animation.getAnimatedValue();        // TODO 使用获取来的值    }});

AnimatorSet
视图动画有同感AnimationSet将各个动画叠加,属性动画当然也有,那就是AnimatorSet,相较于之前的PropertyValuesHolder,AnimatorSet可以更好地控制各个动画的顺序,如用AnimatorSet实现如上面PropertyValuesHolder一样的动画效果
ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(imageView,"translationX",200f);ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(imageView,"scaleX",1f,0f,1f);ObjectAnimator objectAnimator3 = ObjectAnimator.ofFloat(imageView,"scaleY",1f,0f,1f);AnimatorSet animatorSet = new AnimatorSet();animatorSet.setDuration(2000);animatorSet.playTogether(objectAnimator1,objectAnimator2,objectAnimator3);animatorSet.start();

在此AnimatorSet还提供不同的方法来调整各个属性动画的顺序。如:
// 三个动画同时播放animatorSet.playTogether(objectAnimator1,objectAnimator2,objectAnimator3);// 三个动画按顺序播放animatorSet.playSequentially(objectAnimator1,objectAnimator2,objectAnimator3);// objectAnimator1动画与objectAnimator2动画同时播放animatorSet.play(objectAnimator1).with(objectAnimator2);// objectAnimator1动画在objectAnimator2动画播放之前进行,即先播放1动画再播放2动画animatorSet.play(objectAnimator1).before(objectAnimator2);// objectAnimator1动画在objectAnimator2动画播放之后进行,即先播放2动画再播放1动画animatorSet.play(objectAnimator1).after(objectAnimator2);

animate方法给View设置动画
在系统3.0之后,如果动画只执行一次,则可以考虑使用animate()方法来完成动画。即View调用animate()。其简单使用例子如下。
imageView.animate()        .translationX(200f)        .scaleX(2f).scaleY(2f)        .setDuration(2000)        .withStartAction(new Runnable() {    @Override    public void run() {        // 动画开始    }}).withEndAction(new Runnable() {    @Override    public void run() {        // 动画结束        runOnUiThread(new Runnable() {            @Override            public void run() {             }        });    }});

这里调用animate()方法实际是活的一个ViewPropertyAnimator对象,其实际也是属性动画。但这里的属性不是可变数组,且不能设置重复播放。因此用于简单动画叠加或者一次性播放的还是挺方便的。
动画事件的监听
在属性动画执行的过程中,如果需要在某个执行过程做其他操作,则需添加监听事件
objectAnimator.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即可选择需要的事件对其进行监听。
objectAnimator.addListener(new AnimatorListenerAdapter() {    @Override    public void onAnimationCancel(Animator animation) {        super.onAnimationCancel(animation);    }     @Override    public void onAnimationEnd(Animator animation) {        super.onAnimationEnd(animation);    }     @Override    public void onAnimationRepeat(Animator animation) {        super.onAnimationRepeat(animation);    }     @Override    public void onAnimationStart(Animator animation) {        super.onAnimationStart(animation);    }     @Override    public void onAnimationPause(Animator animation) {        super.onAnimationPause(animation);    }     @Override    public void onAnimationResume(Animator animation) {        super.onAnimationResume(animation);    }});

XML中定义属性动画
在res目录下创建anim或是animator文件夹,并新建一个根标签为objectAnimator的xml文件
<!--xml version="1.0" encoding="utf-8"--><objectanimator android:duration="2000" android:propertyname="scaleX" android:valuefrom="1.0" android:valueto="2.0" android:valuetype="floatType" xmlns:android="https://schemas.android.com/apk/res/android"></objectanimator>

在代码中使用
?123Animator animator = AnimatorInflater.loadAnimator(this,R.animator.objectanim);animator.setTarget(imageView);animator.start();    

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道!

本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程