美文网首页
View 视图动画

View 视图动画

作者: 30cf443c3643 | 来源:发表于2018-11-14 16:40 被阅读3次

View Animation(视图动画)使用详解

2018-11-14_163836.png

基础

视图动画可以在一个视图容器内执行一系列简单变换(位置、大小、旋转、透明度),包括

  • TranslateAnimation
  • ScaleAnimation
  • RotateAnimation
  • AlphaAnimation
    例外还有AnimationSet,一个持有其它动画元素 alpha、scale、translate、rotate 或者其它 set 元素的容器。

既可以通过xml来设置,也可以通过代码来控制。比较推荐的方式是xml方法。在res新建anim包

命名

anim 资源名称以小写单词+下划线的方式命名,采用以下规则:

模块名_逻辑名称 _ [方向|序号]

Tween 动画(使用简单图像变换的动画,例如缩放、平移)资源:尽可能以通用的动画名称命名,如 module_fade_in , module_fade_out , module_push_down_in (动画+方向)。

<set
        android:duration="10000"   单位毫秒
        android:fillAfter="true/false" 结束是否停留在当前位置
        android:fillBefore="true/false"
        android:interpolator=""  设定插值器
        android:shareInterpolator="true /false">  是否共用插值器
    <alpha
          android:fromAlpha="float"           动画开始的透明度(0.0到1.0,0.0是全透明,1.0是不透明)
          android:toAlpha="float"/>           

    <scale 
          android:fromXScale="float"         水平方向缩放的起始值 比例
           android:toXScale="float"
           android:fromYScale="float"
           android:toYScale="float"
           android:pivotX="float"                    缩放轴点的x坐标
           android:pivotY="float"/>

    <rotate
        android:fromDegrees="float"  起始旋转角度 0 旋转开始角度,正代表顺时针度数,负代表逆时针度数
        android:toDegrees="float"        比如180
        android:pivotY="float"              
        android:pivotX="float"/>

        旋转起点X轴坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以父控件的左上角加上父控件宽高的50%做为初始点)

    <translate
        android:fromXDelta="float"  x的起始值
        android:toXDelta="float"     x的结束值
        android:fromYDelta="float"      y的起始值
        android:toYDelta="float"/>         y的结束值
</set>

代码调用

Animation anim= AnimationUtils.loadAnimation(this, R.anim.set);
view.startAnimation(anim);

举例view从top位置到原位置

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:fillAfter="false" >
    <translate
        android:fromYDelta="-100%"
        android:toYDelta="0%"/>

</set>

或者代码控制

             TranslateAnimation translate = new TranslateAnimation(
                        Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f,
                        Animation.RELATIVE_TO_SELF, -1f, Animation.RELATIVE_TO_SELF, 0f                );
              translate.setDuration(2000);
              mButton.startAnimation(translate);
        //Animation.RELATIVE_TO_SELF(相对于自身)、Animation.RELATIVE_TO_PARENT(相对于父控件(容器))

另外在上面y是负,在左边x是负,跟手机坐标系一致

其他的方法

方法 解释
reset() 初始化
cancel() 取消
start() 开始
setAnimationListener 设置监听

记自己犯的一个错误,貌似是 因为我对anim多次赋值,导致我调用cancel,动画无法暂停,因为对象不对。

其他

Q:View视图动画为何不能改变View的位置?
补间动画执行之后并未改变 View 的真实布局属性值,产生的动画数据实际是应用在canvas。切记这一点,譬如我们在 Activity 中有一个 Button 在屏幕上方, 我们设置了平移动画移动到屏幕下方然后保持动画最后执行状态呆在屏幕下方,这时如果点击屏幕下方动画执行之后的 Button 是没有任何反应的, 而点击原来屏幕上方没有 Button 的地方却响应的是点击Button的事件。

出自阿里巴巴android开发手册
在有强依赖onAnimationEnd回调的交互时,如播放完毕才能操作页面时,onAnimationEnd可能因为各种异常没有回调,建议加上超时保护或通过postDelay替代onAnimationEnd

  new Handler().postDelay(new Runnable(){
          public void run(){
                   if(view!=null){
                           v.clearAnimation();  
                  }
          }
  })

View的annimation动画结束时,通过clearAnimation释放资源

animation.setAnimationListener(new Animation.AnimationListener() {
                    @Override
                    public void onAnimationStart(Animation animation) {

                    }

                    @Override
                    public void onAnimationEnd(Animation animation) {
                        if(mButton!=null){
                            mButton.clearAnimation();  //判断资源是否被释放了
                        }
                    }

                    @Override
                    public void onAnimationRepeat(Animation animation) {

                    }
                });

帧动画

帧动画 实现像播放幻灯片一样的效果,类似于gif图。它最大的问题还是容易引起OOM的问题
帧动画AnimationDrawable的真正父类是Drawable,所以
在drawable中添加frame.xml。文件的标签是<animation-list>

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">

    <item android:duration="500" android:drawable="@drawable/a"/>
    <item android:duration="500" android:drawable="@drawable/b"/>
    <item android:duration="500" android:drawable="@drawable/c"/>
    <item android:duration="500" android:drawable="@drawable/d"/>
    <item android:duration="500" android:drawable="@drawable/e"/>
</animation-list>

注意

设置ImageView的background为frame.xml,而不是src

使用

 AnimationDrawable drawable = (AnimationDrawable) mImageView.getBackground();
  drawable.start();

尽量不要使用AnimationDrawable ,它在初始化的时候将所有的图片加载到内存中,特别占内存,而且不能释放。释放后下次加载会报错

加载gif

可以通过Glide等开源框架,也可以参考Android自定义View播放Gif动画,主要使用了android.graphics.Movie这个类来加载Gif动画, setTime(int relativeMilliseconds) 设置movie当前处在什么时间,然后找到对应时间的图片帧,范围0 ~ duration。返回是否成功找到那一帧。里面提到一个变量SystemClock.uptimeMillis() // 从开机到现在的毫秒数(手机睡眠的时间不包括在内)

属性动画

通过在一段时间间隔内完成对象从一个属性值到另一个属性值的改变,来实现动画效果
最核心的类有

  • ValueAnimator 实现了整个动画处理逻辑
  • ObjectAnimator 继承自ValueAnimator
  • AnimatorSet 动画的集合

代码

举例1. 改变一个对象的透明度

ObjectAnimator animator = ObjectAnimator.ofFloat(mImageView, "alpha",1f,0f);
                animator.setDuration(2000);
                animator.start();

举例2.绕着x轴旋转

ValueAnimator va=ValueAnimator.ofFloat(0,90);    //控制value值从0到90
                va.setDuration(5000);
                va.start();
                va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {  //设置动画监听
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {               
                        float v = (float) animation.getAnimatedValue();             //拿到0~90之间的某个值 动态的给属性赋值
                        mImageView.setRotationX(v);   //或者va.setTarget(mImageView.getRotationX());然后这边直接mImageView.invalidate();
                    }
                });
scroll.gif

举例3. 对view进行缩放平移都改变

AnimatorSet set = new AnimatorSet();
set.playTogether{
ObjectAnimator animator = ObjectAnimator.ofFloat(mImageView, "scaleX",1f,1.5f);
ObjectAnimator animator = ObjectAnimator.ofFloat(mImageView, "translationX",0,90);
}
set.setDuration(5000).start();

或者
set.play(animator 1).with(animator 2).before(animator 3).after(animator 4).start();

xml控制

在res目录下建animator资源文件夹

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="together/sequentially">  together 同时播放 sequentially集合中的顺序播放
    
    <objectAnimator   对应objectAnimator
        android:propertyName="translateY"   对象的属性名称
        android:duration="1000"  
        android:valueFrom="-100"
        android:valueTo="0"
        android:startOffset="1000"  动画延迟时间
        android:repeatCount="-1"   默认0, -1代表无限循环
        android:repeatMode="restart"
        android:valueType="intType"/>  propertyName属性的类型


  <animator   对应ValueAnimator 但是没有propertyName属性
             ..../>
</set>

使用动画:
Animator animator = AnimatorInflater.loadAnimator(context, R.animator.set_animation); 
// 载入XML动画 
animator.setTarget(view); // 设置动画对象 
animator.start();

说明

控件的属性需要提供set get方法,因为他是通过反射来实现。如果没有对应get,set的方法,可以通过AnimatorUpdateListener来实现

动画监听

View设置监听

        view.addAnimatorUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                
            }
        });
        view.addAnimatorListener(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) {

            }
        });

或者属性动画设置监听

animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
               
            }
        });
        animator.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) {

            }
        });

插值器

插补器Interpolator配图详解
Android 属性动画探究(一)——Interpolator解析与自定义

相关文章

  • Android View Animation(视图动画)

    View Animation(视图动画)1.1 View动画的概述及种类视图动画的作用对象是View,支持四种动画...

  • Android动画

    view动画(视图动画)包含帧动画 属性动画 valueAnimator

  • Android 动画 | 艺术探索笔记

    Android 动画分为两大类 视图动画 属性动画 视图动画(View animation) 视图动画分为 补间动...

  • Android 动画

    View Animation(视图动画) 概述: 视图动画,也叫 Tween (补间)动画可以在一个视图容器内执行...

  • Android 动画

    View Animation(视图动画) 概述: 视图动画,也叫 Tween (补间)动画可以在一个视图容器内执行...

  • Android动画的灵魂舞曲(二)

    视图动画(View Animation) 视图动画中有两个类型: 1、渐变动画(Tween animation)2...

  • 06 Android 动画

    1 View Animation(视图动画) 1.1 概述: 视图动画,也叫 Tween (补间)动画可以在一个视...

  • Android动画

    Android动画 动画类型 视图动画(View Animatio)补间动画(Tween Animation)逐帧...

  • 视图(view)相关

    动画种类 通过view.animate设置图层视图位置(默认动画) 通过view.animate({anchor,...

  • Android动画目录

    Android中的动画分类 Animation(动画):View Animation(视图动画):帧动画(Fram...

网友评论

      本文标题:View 视图动画

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