动画

作者: 微罗妮卡 | 来源:发表于2018-06-04 15:14 被阅读0次

    Animation

    Android 框架提供了两种动画系统:属性动画和补间动画,这两者都是可选择使用的,但是像比较而言,属性动画是更好的选择,因为其更灵活而且提供更多的属性,除了这两个之外,你还可以利用帧动画,他允许你加载Drawable资源然后以一帧一帧的形式展示他们。
    1.Property Animation
    引进在Android 3.0(11),它可以让对象的任何属性做动画,包括那些不被渲染到屏幕上的。该系统是可扩展的,并且可以让您的自定义类型的动画属性。
    2.View Animation
    补间动画是以前的系统提供的,仅仅可以作用在View上面,它是比较容易使用,并提供足够的功能,以满足许多应用程序的需求。
    3.Drawable Animation
    帧动画可以展示drawable资源一个接一个,像一卷胶卷。如果你想让事情更容易与drawable资源代表这个方法的动画是很有用的,比如一个进程图。

    效果:类似gif动图
    实现方式:
    res/drawable/animation_list_filling.xml

    <?xml version="1.0" encoding="utf-8"?> 
    <animation-list xmlns:android="http://schemas.android.com/apk/res/android"          
          android:oneshot="true">  执行一次
        <item  
          android:duration="500"
            android:drawable="@drawable/ic_heart_0"/>
        <item  
          android:duration="500"      
          android:drawable="@drawable/ic_heart_25"/>  
        <item    
          android:duration="500"     
          android:drawable="@drawable/ic_heart_50"/>    
       <item   
         android:duration="500"     
         android:drawable="@drawable/ic_heart_75"/>   
      <item     
         android:duration="500"   
         android:drawable="@drawable/ic_heart_100"/> 
     </animation-list>
    

    代码运用,获得背景,开启动画

    ImageView mImageViewEmptying =
     (ImageView) findViewById(R.id.animation_list_filling);
     ((AnimationDrawable)mImageViewEmptying.getBackground())
    .start();
    
    

    例子二

    <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
        android:oneshot="true">
        <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
        <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
        <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
    </animation-list>
    AnimationDrawable rocketAnimation;
    public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
      rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
      rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
    }
    public boolean onTouchEvent(MotionEvent event) {
      if (event.getAction() == MotionEvent.ACTION_DOWN) {
        rocketAnimation.start();
        return true;
      }
      return super.onTouchEvent(event);
    }
    
    

    问题 如何停止动画,让它动画正好播放在指定帧
    anim.selectDrawable(0); //选择当前动画的第一帧,然后停止
    anim.stop();

    二 接下来我的第二不常用 View Animation

    它可以实现补间动画(tween animation) ,首先回答一下困扰我很久的问题,补间是个什么鬼?
    补间动画,又叫做中间帧动画,只需给出起始和终点动画,中间动画由软件自动生成.
    实现方式 xml files and hard-croding 推荐使用xml files 可重用,易读
    主要实现类 AnimationSet 和 Animation的子类

    在res/anim 下建立xml文件.
    顺序也可以一起执行

    Interpolator

    三:属性动画:Property Animation

    属性动画:
    proprety animitor
    (1)与 view animaitor 区别
    支持除了view控件以外的动画
    view animator只是重绘了,但并未改变其真实位置

    结构

    Animator
         ValueAnimator   并不能给某个对象或属性添加动画,如果想实调用ValueAnimator.AnimatorUpdateListener
          ObjectAnimator  大多数使用这个动画,但是它的限制多一些,比如要求特定的acessor方法对目标对象存在。
    包含动画执行周期,是加速还是减速(一种插值运算,可以设置)
    
    Evaluators    计算属性动画的变化值
      IntEvaluator     默认给定的计算方式
      FloatEvaluator
          ArgbEvaluator  对颜色值的变化
          TypeEvaluator 一个接口,支持自定义
    
    

    Interpolator 插值器,加速或减速

    属性 含义
    @android:anim/accelerate_decelerate_interpolator 先加速后减速
    @android:anim/accelerate_interpolator 加速
    @android:anim/decelerate_interpolator 减速
    @android:anim/anticipate_interpolator 先向动画的反方向移动一点,在沿动画的方向移动
    @android:anim/anticipate_overshoot_interpolator 先向动画的反方向移动一点,在沿动画的方向移动,超过指定终点一点在回弹到终点
    @android:anim/overshoot_interpolator 动画到最后的位置会向反方向移动一点。
    @android:anim/bounce_interpolator 在终点回弹几次在停在终点
    @android:anim/cycle_interpolator 动画周期移动
    @android:anim/linear_interpolator 动画匀速移动

    1.alpha( 渐变)

    名称 含义 备注
    android:fromAlpha 动画开始时的透明度 float[0,1] 0表示完全透明,1表示完全不透明
    android:toAlpha 动画结束时的透明度 float[0,1] 0表示完全透明,1表示完全不透明

    2.scale( 缩放)

    名称 含义 备注
    android:fromXScale 动画开始时,X坐标上伸缩的尺寸 float[0,1] 0.0表示收缩到没有 1.0表示正常无收缩 小于1收缩 大于1放大
    android:toXScale 动画结束时,X坐标上伸缩的尺寸 float[0,1] 0.0表示收缩到没有 1.0表示正常无收缩 小于1收缩 大于1放大
    android:fromYScale android:toYScale android:privotY
    android:privotX 动画相对于物件的X的开始位置 [0%,100%]

    50%表示中间

    名称 含义 备注
    android:fromXDelta 动画开始时X坐标上的位置 integer 默认以自己为参照物
    android:toXDelta android:fromYDelta android:toYDelta

    3.translate(平移)

    名称 含义 备注
    android:fromXDelta 动画开始时X坐标上的位置 integer 默认以自己为参照物
    android:toXDelta android:fromYDelta android:toYDelta
    名称 含义 备注
    android:fromDegrees(角度,度数) 动画开始时控件的角度 负数:逆时针旋转 正数:顺时针旋转
    android:fromDegrees 动画结束时控件的角度 ---
    android:pivotX 动画相对于物件的X的开始位置 [0%,100%],50%表示中间
    android:pivotY --- ---

    4.rotate(旋转)

    名称 含义 备注
    android:fromDegrees(角度,度数) 动画开始时控件的角度 负数:逆时针旋转 正数:顺时针旋转
    android:fromDegrees 动画结束时控件的角度 ---
    android:pivotX 动画相对于物件的X的开始位置 [0%,100%],50%表示中间
    android:pivotY --- ---
    image.png
    ValueAnimator应用
    ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f,1f);
    
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                   @Override
                   public void onAnimationUpdate(ValueAnimator animation) {
                       //得到的值就是在上面ValueAnimator.ofFloat(0f,1f);中指定的,会在给定的时间内变化
                       //有时需要调invalidate()方法
                       float value = (float)animation.getAnimatedValue();
                       imageView.setScaleX(value);
                       //
                       Log.d("MainActivity","属性值"+value);
                     //  imageView.setColorFilter((int)value);
                      // imageView.invalidate();
    
                   }
               });
              
         
       
        valueAnimator.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) {
    
                   }
               });
               
    
       valueAnimator.setDuration(1000);
              valueAnimator.start();
     });    
    
     
    }
    注: 如果不想实现所有方法,可以使用AnimatorListenerAdapter,它是一个抽象类,实现了AnimatorListener,和AnimatorPauseListener
    
    
    
    标识 含义
    APPEARING (appearing) 一个标识 指示动画作用的控件显示在容器中
    CHANGE_APPEARING (change_appearing) 一个标识 指示动画作用的控件正在变化由于一个新的item出现在容器中
    DISAPPEARING (disappearing) 一个标识 指示动画作用的控件消失在容器中
    CHANGE_DISAPPEARING (change_disappearing) 一个标识 指示动画作用的控件正在变化由于一个新的item出消失容器中

    为ViewGroup 添加动画 (为里面的itemView在显示或消失的时候添加动画,或显示的view的一些动画处理)
    LayoutTrasition setAnimator()

    标识 含义
    APPEARING (appearing) 一个标识 指示动画作用的控件显示在容器中
    CHANGE_APPEARING (change_appearing) 一个标识 指示动画作用的控件正在变化由于一个新的item出现在容器中
    DISAPPEARING (disappearing) 一个标识 指示动画作用的控件消失在容器中
    CHANGE_DISAPPEARING (change_disappearing) 一个标识 指示动画作用的控件正在变化由于一个新的item出消失容器中
    为ViewGroup添加动画的过程(为里面的itemView在显示或消失的时候添加动画,或显示的view的一些动画处理)
    
    tansition = new LayoutTransition();
    tansition.setDuration(8000);
    ObjectAnimator animIn = ObjectAnimator.ofFloat(null, "rotationY", 90f,0f)
    .setDuration( tansition.getDuration(LayoutTransition.APPEARING));
    
    tansition.setAnimator(LayoutTransition.APPEARING, animIn);
    
    animIn.addListener(new AnimatorListenerAdapter() {
       public void onAnimationEnd(Animator anim) {
           View view = (View) ((ObjectAnimator) anim).getTarget();
           view.setRotationY(0f);
       }
    });
    
    
    ll.setLayoutTransition(tansition);
    
    源码分析:
    setLayoutTransition()
    mTansition!=null :清掉动画,清掉监听器
    mTabsition==null :赋值,mTabsition == tansition 设置监听 TransitionListener
    监听器:
    if (transitionType == LayoutTransition.DISAPPEARING) {
       startViewTransition(view);  //把消失的view保存起来ArraayList
    }
    Called when a view's visibility has changed. Notify the parent to take any appropriate
    * action.onChildVisibilityChanged() //子布局显示改变
    if 显示:
       mTranstion.showChild(this,child,oldVisibility){
                    addChild(parent,child,oldVisibility==View.GONE)
    }
    else :
             mTranstion.hideChild(this,child,newVisibibility)
    
    onChildVisibilityChanged
    addViewInner
    setLayoutTransition
    removeDetachedView
    layout
    
    

    specifying keyframes 指定关键帧

    |

    keyFrame是一个 时间/值 对,通过它可以定义一个在特定时间的特定状态,即关键帧,而且在两个keyFrame之间可以定义不同的Interpolator,就好像多个动画的拼接,第一个动画的结束点是第二个动画的开始点。KeyFrame是抽象类,要通过ofInt(),ofFloat(),ofObject()获得适当的KeyFrame,然后通过PropertyValuesHolder.ofKeyframe获得PropertyValuesHolder对象,如以下例子:

    上述代码的意思为:设置btn对象的width属性值使其:

    • 开始时 Width=400
    • 动画开始1/4时 Width=200
    • 动画开始1/2时 Width=400
    • 动画开始3/4时 Width=100
    • 动画结束时 Width=500

    第一个参数为时间百分比,第二个参数是在第一个参数的时间时的属性值。

    定义了一些Keyframe后,通过PropertyValuesHolder类的方法ofKeyframe一个PropertyValuesHolder对象,然后通过ObjectAnimator.ofPropertyValuesHolder获得一个Animator对象。

    用下面的代码可以实现同样的效果(上述代码时间值是线性,变化均匀):

    ObjectAnimator oa=ObjectAnimator.ofInt(btn2, "width", 400,200,400,100,500);
    oa.setDuration(2000);
    oa.start();
    
    

    在横屏中,ImageView位于屏幕右边,向左平移
    首先无论在横屏还是竖屏中,都是水平x轴,垂直y轴

    动画移动的原点是控件的左上角
    当控件指定未屏幕右侧的时候,原点也为控件所在位置的左上角

    相关文章

      网友评论

          本文标题:动画

          本文链接:https://www.haomeiwen.com/subject/rrbthftx.html