当前位置: 首页 > 科技观察

Android动画全套技巧

时间:2023-03-11 20:30:37 科技观察

【引自MrXI的博客】1.AndroidView动画框架Animation框架定义了透明、旋转、缩放、位移等几种常用的动画,控制着整个View。实现原理是每次绘制view时,View所在的ViewGroup中的drawChild函数获取View的Animation的Transformation值,然后调用canvas.concat(transformToApply.getMatrix())来通过矩阵运算完成动画帧。如果没有完成,继续调用invalidate()函数,开始下一次绘制驱动动画,完成整个动画的绘制。View动画使用方便,效果丰富。它提供了四种动画方法:AlphaAnimation、RotateAnimation、TranslateAnimation、ScaleAnimation,并提供动画集AnimationSet,可以混合使用多种动画。在Android3.0之前,视图动画是唯一的,但是随着Android3.0之后属性动画框架的引入,它的风景大不如前了。与属性动画相比,视图动画的一个非常大的缺陷就是不具有交互性。当一个元素发生视图动画时,它的响应事件位置仍然在动画之前,所以视图动画只能做普通的动画Effect,避免交互的发生。但是它的优点也非常明显,就是效率比较高,使用方便。Viewanimation非常简单易用,不仅可以通过XML文件描述一个动画过程,还可以用代码来控制整个动画过程。(1)透明动画是给视图增加透明度的变换动画。AlphaAnimationaa=newAlphaAnimation(0,1);aa.setDuration(1000);view.startAnimation(aa);(2)、旋转动画给视图添加旋转变换动画。RotateAnimationra=newRotateAnimation(0,360,100,100);ra.setDuration(1000);view.startAnimation(ra);参数是旋转的起始角度和旋转中心点坐标,当然可以设置参数控制旋转动画的参考系,这里设置旋转动画的参考系为中心。RotateAnimationra1=newRotateAnimation(0,360,RotateAnimation.RELATIVE_TO_SELF,0.5F,RotateAnimation.RELATIVE_TO_SELF,0.5F);(3)、位移动画是在视图移动时增加位移动画。TranslateAnimationta=newTranslateAnimation(0,200,0,300);ta.setDuration(1000);view.startAnimation(ta);(4),缩放动画为视图缩放添加动画效果ScaleAnimationssa=newScaleAnimation(0,2,0,2);sa。setDuration(1000);view.startAnimation(sa);和旋转动画一样,缩放动画也可以设置洛方的中心点,设置中心为自己的中心效果ScaleAnimationssa1=newScaleAnimation(0,1,0,1,Animation.RELATIVE_TO_SELF,0.5F,Animation.RELATIVE_TO_SELF,0.5F);sa1.setDuration(1000);view.startAnimation(sa1);(5)、动画集可以通过AnimationSet以组合的形式显示动画:AnimationSetas=newAnimationSet(true);as.setDuration(1000);AlphaAnimationaa=newAlphaAnimation(0,1);aa.setDuration(1000);as.addAnimation(aa);RotateAnimationra=newRotateAnimation(0,360,100,100);ra.setDuration(1000);as.addAnimation(ra);TranslateAnimationta=newTranslateAnimation(0,200,0,300);ta.setDuration(1000);as.addAnimation(ta);ScaleAnimationssa=newScaleAnim化(0,2,0,2);sa.setDuration(1000);as.addAnimation(sa);view.startAnimation(as);可以直接复制代码运行看看效果!对于动画事件,Android也提供了相应的监听回调,代码:as.setAnimationListener(newAnimation.AnimationimationListener(){@OverridepublicvoidonAnimationStart(Animationanimation){//动画开始}@OverridepublicvoidonAnimationEnd(Animationanimation){//动画结束}@OverridepublicvoidonAnimationRepeat(Animationanimation){//动画动画}});2.Android3.0之前已经实现了属性动画有些动画框架Animation有一些局限性——动画只是改变显示,不能响应事件。因此,在Android3.0之后,Google提出了属性动画等新的动画框架来实现更丰富的效果。在Animator框架中,AnimatorSet和ObjectAnimator一起使用最多,而ObjectAnimator用于更精细的控制,只控制一个对象的一个??属性值,多个ObjectAnimator组合到AnimatorSet中组成一个动画。而ObjectAnimator是可以自动驱动的,可以调用setFrameDelay(longframeDelay)来设置动画帧之间的间隔时间。最重要的是属性动画实际上是通过调用属性的get和set方法来控制一个View的属性值,所以强大的属性动画框架基本可以实现所有的动画效果。(1)、ObjectAnimatorObjectAnimator是属性动画框架中最重要的实现类,创建一个ObjectAnimator只需要通过其静态工厂类直接返回一个ObjectAnimator对象即可。参数包括一个对象和对象的属性名,但是这个属性还必须有get和set函数,set函数会通过Java反射机制在内部调用来修改对象属性的值。同样,你也可以调用setInterpolator来设置对应的差分器。接下来,想象一下向Button添加翻译动画。使用之前的动画帧平移后,不会触发点击事件。点击的有效区域还是原来的地方,点击移动后的地方不会发生点击事件。属性动画不同。它实际上改变了一个View的属性,所以事件响应区域也随之改变。这时候点击被移动的按钮就会响应点击事件。属性动画翻译代码如下:ObjectAnimatoranimator=ObjectAnimator.ofFloat(imageView,"translationX",200F);animator.setDuration(300);animator.start();在使用ObjectAnimator的时候,很重要的一点是操作Attributes必须有get和set方法,否则ObjectAnimator将无法工作。以下是常用的属性:translationX和translationY:这两个属性控制View对象的位置,从其布局容器的左上角坐标开始为增量。rotation、rotationX和rotationY:这三个属性控制View对象围绕支点的2D和3D旋转。scaleX和scaleY:这两个属性控制View对象围绕其支点的2D缩放。pivotX和pivotY:这两个属性控制View对象的支点位置,并围绕这个支点进行旋转和缩放变换。默认情况下,枢轴的位置是View对象的中心点。x和y:这两个简单实用的属性描述了View对象在其容器中的最终位置,即初始左上角坐标与translationX和translationY值的累加和。alpha:表示View对象的alpha透明度。默认值为1(不透明),0表示完全透明(不可见)。根据上面我们知道,视图动画实现的动画效果基本都包含在这里了。那么如果一个属性没有get和set方法,属性动画是不是就束手无策了呢?答案是不。Google在应用层提供了两种解决方案来解决这个问题。一种是自定义一个属性类或包装类。为该属性间接添加get和set方法;还是通过ValueAnimator,下面内容中提到的ValueAnimator,先看使用包装类的方法给一个属性添加get和set方法,代码如下:publicWrapperView(ViewmTarget){this.mTarget=mTarget;}publicintgetWidth(){returnmTarget.getLayoutParams().width;}publicvoidsetWidth(intwidth){mTarget.getLayoutParams().width=width;mTarget.requestLayout}out();通过上面的代码,给它包裹了一个属性,给它提供了get和set方法。使用时,只需操作包装类,间接调用get、set方法即可。代码如下:WrapperViewwrapperView=newWrapperView(view);ObjectAnimator.ofInt(wrapperView,"width",500).setDuration(5000).start();(2)、PropertyValuesHolder类似于视图动画中的AnimationSet。在属性动画中,如果要同时对同一个对象的多个属性应用多个动画,可以使用PropertyValuesHolder来实现。比如平移动画,如果在平移过程中改变X轴和Y轴的缩放,可以这样实现,代码:PropertyValuesHolderpvh1=PropertyValuesHolder.ofFloat("translationX",300);PropertyValuesHolderpvh2=PropertyValuesHolder.ofFloat("scaleX",1f,0,1f);PropertyValuesHolderpvh3=PropertyValuesHolder.ofFloat("scaleY",1f,0,1f);ObjectAnimator.ofPropertyValuesHolder(pvh1,pvh2,pvh3).setDuration(1000).start();在代码中,分别使用PropertyValuesHolder对象来控制translationX、scaleX、scaleY这三个属性,最好调用ObjectAnimator.ofPropertyValuesHolder方法实现多属性动画的联合动作。整个实现方式和AnimatorSet的使用非常相似。(3)、ValueAnimatorValueAnimator在属性动画中占有非常重要的地位。虽然没有ObjectAnimator那么炫,但它是属性动画的核心。ObjectAnimator也是继承自ValueAnimator。publicfinalclassObjectAnimatorextendsValueAnimatorValueAnimator本身不提供任何动画效果,它更像是一个值生成器,用来生成具有一定规则的数字,以便于调用者控制动画的执行过程,ValueAnimator的一般用途:通常监听ValueAnimator的AnimatorUpdateListener完成动画的变换。ValueAnimatorvalueAnimator=ValueAnimator.ofFloat(0,100);valueAnimator.setTarget(imageView);valueAnimator.setDuration(1000).start();valueAnimator.addUpdateListener(newValueAnimator.AnimatorUpdateListener(){@OverridepublicvoidonAnimationUpdate(ValueAnimatoranimation(.Floatanimation){Floatvalue=)getAnimatedValue();}});(4)动画事件的监听一个完整的动画有Start、Repeat、End、Cancel四个过程。Android提供了一个接口来方便地监听这四个事件:}@OverridepublicvoidonAnimationCancel(Animatoranimation){}@OverridepublicvoidonAnimationRepeat(Animatoranimation){}});anim.start();很多时候我们只关心onAnimationEnd事件,所以Android也提供了一个AnimatorListenerAdapter让我们选择需要的事件听:anim.addListener(newAnimatorListenerAdapter(){@OverridepublicvoidonAnimationEnd(Animatoranimation){super.onAnimationEnd(animation);}});(***nimatorSet同时作用于一个属性的多个属性动画效果,这个效果之前已经使用PropertyValuesHolder实现了,而AnimatorSet不仅可以实现这个效果,还可以实现更多精确顺序控制,同样是使用PropertyValuesHolder实现上面演示的动画效果,如果使用AnimatorSet实现,代码如下:ofFloat(imageView,"scaleX",1f,0f,1f);ObjectAnimatorobjectAnimator2=ObjectAnimator.ofFloat(imageView,"scaleY",1f,0f,1f);AnimatorSetanimatorSet=newAnimatorSet();animatorSet.setDuration(1000);animatorSet.playTogether(objectAnimator,objectAnimator1,objectAnimator2);animatorSet.start();在属性动画中,AnimatorSet通过playTogether()、playSquentially()、animSet.play().width()、defore()、and之后()。工作模式,从而实现对动画播放顺序的精确控制。(6)在XML中使用属性动画。和视图动画一样,属性动画也可以直接写在XML文件中,代码:前提就是用XML来定义属性动画。XML文件必须放在res/animator/filename.xml文件夹下才能被识别,否则无法识别。发现属性动画和视图动画在XML文件中的写法非常相似。程序中使用:Animatoranim=AnimatorInflater.loadAnimator(this,R.animator.filename);anim.setTarget(view);anim.start();(7),View的animate方法是Android3.0以后的,谷歌给出ViewAddedanimate方法直接驱动属性动画,代码如下:imageView.animate().alpha(0).y(300).setDuration(300).withStartAction(newRunnable(){@Overridepublicvoidrun(){}}).withEndAction(newRunnable(){@Overridepublicvoidrun(){runOnUiThread(newRunnable(){@Overridepublicvoidrun(){}});}}).start();3.Android布局动画布局动画是指作用于ViewGroup,在给ViewGroup添加View时添加一个动画过渡效果。最简单的布局动画是在ViewGroupXML中,使用如下代码开启布局动画:android:animateLayoutChanges="true"通过上面的设置,当ViewGroup被添加到View中时,子View会呈现一个过渡效果也就是逐渐显示,但是这个效果是Android默认显示的过渡效果,不能用自定义动画代替。也可以通过LayoutAnimatorController类自定义子View的过渡效果,添加视图动画,使子View出现缩放动画效果。代码:LinearLayoutll=(LinearLayout)findViewById(R.id.ll);ScaleAnimationsa=newScaleAnimation(0,1,0,1);sa.setDuration(2000);//设置布局动画显示LayoutAnimationControllerlac=newLayoutAnimationController(sa,0.5f);//设置布局动画ll.setLayoutAnimation(lac);LayoutAnimationController第一个参数是需要作用的动画,第二个参数是各个子View显示的延迟时间。当延迟时间不为0时,可以设置子View的显示顺序。//顺序publicstaticfinalintORDER_NORMAL=0;//随机publicstaticfinalintORDER_REVERSE=1;//逆序publicstaticfinalintORDER_RANDOM=2;4.Interpolators——Interpolators插值器是动画中一个非常重要的概念。插值器可以定义动画转换率。这很像物理学中的加速度,其作用主要是控制目标变量的变化值做出相应的变化。AccelerateDecelerateInterpolator在动画开始和引入时缓慢变化,中间加速BounceInterpolator在动画结束时反弹CycleInterpolator并循环动画特定次数,速率沿正弦曲线变化DecelerateInterpolator先快后慢在动画开始时LinearInterpolator以恒定的速率变化OvershootInterpolator向前抛出一定值后,返回到原来的位置。PathInterpolator路径插值器未完成,待续。..5.开源代码库***分享一个自己积累了很久的代码库,只有你想不到,没有你不会用,欢迎starhttps://github.com/xijiufu由于github服务器在美国,有时候访问很慢,可以提供一个开源的中文地址库,两个仓库的代码同步更新:http://git.oschina.net/西九府