《Android开发艺术探索》读书笔记 (7) 第7章 Android动画深入分析

本节和《Android群英传》中的第七章Android动画机制与使用技巧有关系,建议先阅读该章的总结

第7章 Android动画深入分析

http://blog.csdn.net/lijinhua7602/article/details/41972303

7.1 View动画
  (1)android动画分为view动画、帧动画和属性动画,属性动画是API 11(Android 3.0)的新特性,帧动画一般也认为是view动画,分为平移动画、缩放动画,旋转动画、透明度动画,除了这四种经典的变换效果外,帧动画也属于View动画。

7.1.1View动画的种类
      四个子类:TranslateAnimation、scaleAnimation、RotateAnimation和AlphaAnimation----具体用法看上面的连接地址
(2) AnimationSet 的属性 android:shareInterpolator 表示集合中的动画是否共享同一个插值器,如果集合不指定插值器,那么子动画需要单独指定所需的插值器或者使用默认值。
(3)自定义动画需要继承 Animation 抽象类,并重新它的 initialize applyTransformation 方法,在initialize方法中做一些初始化工作,在applyTransformation方法中进行相应的矩阵变换,很多时候需要采用 Camera 类来简化矩阵变换的过程,这里提供一个自定义View动画的例子,这个例子来自于Android的ApiDemos中的一个自定义View动画Rotate3dAnimation,Rotate3dAnimation可以围绕Y轴旋转并且同时沿着z轴平移从而实现一种类似于3D的效果,参考apiDemo中的Rotate3dAnimation。
(4)帧动画是顺序播放一组预先定义好的图片,使用比较简单,但是容易引起OOM,所以在使用的时候应尽量避免使用过多尺寸较大的图片

7.2 view动画的特殊使用场景
    比如在ViewGroup中可以控制子元素的出场效果,在Activity中可以实现不同Activity之间的切换效果。

   7.2.1布局动画(LayoutAnimation)属性分析

      LayoutAnimation作用于ViewGroup,为ViewGroup指定一个动画,这样当它的子元素出场时都会具有这种动画效果,这种效果常常被用在ListView上,我们时常会看到一种特殊的ListView,它的每个item都以一定的动画形式出现,其实这并非什么高深的技术,它使用的就是LayoutAnimation,LayoutAnimation也是一个View动画,为了给ViewGroup的子元素加上出场效果,按以下几个步骤:

    (1) 定义LayoutAnimation,如下所示:

<layoutAnimation
xmlns:android="http://schemas.android.com/apk/res/android"
android:delay="0.5"
android:animationOrder="reverse"
android:animation="@anim/anim_item"/>

    android:delay:表示子元素开始动画的时间延迟,比如子元素入场动画的时间周期是300ms,那么0.5表示每个子元素都需要延迟150ms才能播放入场动画

        android:animationOrder  表示子元素动画的顺序,有三种选项:normal、reverse和random,其中normal表示顺序显示,reverse表示逆向显示,radom则是随机播放入场动画。

       android:animation   为子元素指定具体的入场动画。

      给ViewGroup指定LayoutAnimation的两种方式

//xml
android:layoutAnimation="xxx"
//java
Animation animation = AnimationUtils.loadAnimation(this, R.anim.anim_item);
LayoutAnimationController controller = new LayoutAnimationController(animation);
controller.setDelay(0.5f);
controller.setOrder(LayoutAnimationController.ORDER_NORMAL);
listView.setLayoutAnimation(controller);
(2)Activity切换效果

直接调用overridePendingTransition(int inAnim, int outAnim)方法,必须要在在startActivity方法后或者finish方法之后被调用才能生效,设置进入或者退出的动画效果,enterAnim--表示Actiivty补打开,exitAnim表示被退出的动画。

Fragment也可以添加切换动画,由于Fragment是在API11中新引入的类,因此为了兼容性我们需要使用support-v4这个兼容包,在这种情况下我们可能通过FragmentTransation中的setCustomAnimations方法来添加切换动画
还有其他方式可以给Activity添加切换动画效果,但是往往有兼容性限制,参见《Android群英传》第七章Android动画机制与使用技巧

7.3 属性动画
http://blog.csdn.net/lmj623565791/article/details/38067475

http://blog.csdn.net/singwhatiwanna/article/details/17853275

   属性动画中有ValueAnimator、ObjectAnimator和AnimatorSet等概念

 (1)属性动画可以对任意对象的属性进行动画而不仅仅是view,动画默认的时间间隔是300ms,默认帧率是10ms/帧

  (2)属性动画几乎是无所不能,但是它是从API 11才有的,所以存在兼容性问题,可以考虑使用开源动画库nineoldandroids。它的功能和系统原生的android.animations.*中的类的功能完全一致,使用方法也是完全一样,因此能在Android的低版本上运行,它的本质还是View动画,只要我们用nineoldandroids编写动画,那么就能运行在所有的android系统上,比较常用的几个动画类是ValueAnimator,ObjectAnimator和AnimatorSet,其中ObjectAnimator继承自ValueAnimator。

(3)属性android:repeatMode表示动画的重复模式,repeat表示连续重复播放,reverse表示逆向重复播放,也就是第一次播放完后第二次倒着播放动画,第三次还是重头开始播放动画,第四次再倒着播放,以此类推。

    在实际开发中建议采用代码来实现属性动画,这是因为通过代码来实现比较简单,更重要的是,很多时候一个属性的起始值是无法提前确定的,

(4)插值器和估值器:属性动画实现非匀速动画的重要手段
时间插值器(TimeInterpolator)的作用是根据时间流逝的百分比计算出当前属性值改变的百分比,系统内置的插值器有线性插值器(LinearInterpolator)匀速动画、加速减速插值器(AccelerateDecelerateInterpolator)动画两头慢中间快、减速插值器(DecelerateInterpolator)动画越来越慢。
类型估值器(TypeEvaluator)的作用是根据当前属性改变的百分比计算出改变后的属性值,系统内置的估值器有IntEvaluatorFloatEvaluatorArgbEvaluator 属性动画中的插值器(Interpolator)和估值器(TypeEvaluator)很重要,它们是实现非匀速动画的重要手段

AnimatorListener:监听动画的开始、结束、取消以及重复播放;
AnimatorUpdateListener:监听动画的整个过程,动画每播放一帧的时候onAnimationUpdate方法就会被回调一次。

(6)对任意属性做动画的方法:封装原始对象或者ValueAnimator

  属性动画的原理:属性动画要求动画作用的对象提供该属性的get和set方法,属性动画根据外界传递的该属性的初始值和最终值,以动画的效果多次去调用set方法,要想要动画生效,要同时满足两个条件:

  (1) Object必须要提供setAbc方法,如果动画的时候没有初始值,还要提供getAbc方法,

  (2) object的setAbc对属性abc所做的改变能够通过某种方法反映出来。

  针对上述问题,我们有3种解决方法:

     给你的对象加上get和set方法,如果你有权限的话:

     用一个类来包装原始对象,间接为其提供get与set方法:

     private void performAnimate()

{

ViewWrapper wrapper = new ViewWrapper(mButton);

               ObjectAnimator.ofInt(wrapper,"width",500).setDuration(5000).start();

}

  public void onClick()

{

if(v==mButton)

{

performAnimate();

}

}

 privae static class ViewWrapper

{

private View mTarget;

        public ViewWrapper(View target)

{

mTarget = target;

}

public int getWidth()

{

return mTarget.getLayoutParams().width;

}

public  void setWidth(int width)

{

mTarget.getLayoutParams().width = width;

               mTarget.requestLayout();

}

}

    采用ValueAnimator,监听动画过程,自己实现属性的改变。

    ValueAnimator本身不作用于任何对象,监听其动画过程,,在动画过程中修改我们的对象的属性值

    private void performAnimate(final View target,final int start,final int end)

   {

ValueAnimator valueAnimator = ValueAnimator.ofInt(1,100);

       valueAnimator.addUpdateListener(new AnimatorUpdateListener(){

private IntEvaluator mEvaluator = new IntEvaluator();

public void onAnimationUpdate(ValueAnimator animator){

// 获取当前动画的进度值,整形,1-100之间

                              int crrentValue = (Integer) animator.getAnimatedValue();

// 获得当前进度占整个动画过程的比例,浮点型,0-1之间

                             float fraction = animator.getAnimatedFraction();

    // 直接调用整形估值器,通过比例计算出宽度,然后再设给buton

   target.getlayoutParams().width = mEvaluator.evaluate(fraction,start,end);

  target.requestLayout();

}

});

}

 (7)属性动画的工作原理:属性动画需要运行在有Looper的线程中,反射调用get/set方法

7.4 使用动画的注意事项

(1)OOM:尽量避免使用帧动画,使用的话应尽量避免使用过多尺寸较大的图片;
(2)内存泄露:属性动画中的无限循环动画需要在Activity退出的时候及时停止,否则将导致Activity无法释放而造成内存泄露。view动画不存在这个问题;
(3)兼容性问题:某些动画在3.0以下系统上有兼容性问题;
(4)view动画的问题:view动画是对view的影像做动画,并不是真正的改变view的状态,因此有时候动画完成之后view无法隐藏,即setVisibility(View.GONE)失效了,此时需要调用view.clearAnimation()清除view动画才行。
(5)不要使用px;
(6)动画元素的交互:在android3.0以前的系统上,view动画和属性动画,新位置均无法触发点击事件,同时,老位置仍然可以触发单击事件。从3.0开始,属性动画的单击事件触发位置为移动后的位置,view动画仍然在原位置
(7)硬件加速:使用动画的过程中,建议开启硬件加速,这样会提高动画的流畅性。

其他学习资料
1.Android样式的开发:View Animation篇
2.Android样式的开发:Property Animation篇

OK,本章结束,谢谢阅读。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值