首页 > 程序开发 > 移动开发 > Android >

Day34-Animation 动画

2016-09-17

游戏:利用自定义View的绘制方法,开启线程频繁的刷新界面,形成动画; Android 视图动画:针对 View 以及View的子类。 Android 属性动画:针对定义的属性,大部分可以操作View

根据人眼视觉残留现象,连续播放一些列的图像,形成动画效果。

Android中的动画:

游戏:利用自定义View的绘制方法,开启线程频繁的刷新界面,形成动画; Android 视图动画:针对 View 以及View的子类。 Android 属性动画:针对定义的属性,大部分可以操作View

补间动画

Android根据起始状态和结束状态,进行控件的移动、旋转、缩放等显示效果的变化,形成一个动画

实现方式

XML 定义动画 (Android官方推荐)
xml 定义在 res/anim/ 文件夹下面; 这种 anim动画,需要通过 AnimationUtils 来加载

代码实现动画(可扩展性差)

补间动画,就是指定开始状态,并且指定结束状态,Android系统自动的在这两个状态之间进行填充,形成连续的动画,就被称为补间动画

代码从XML中加载 动画对象; 给需要处理的控件,设置动画就可以播放了;

补间动画特点

通过指定时间、起始状态、结束状态,通过Android系统API,来进行动态效果的呈现; 补间动画,播放完成执行,控件将会还原为原始的位置、状态; 可以根据动画的播放情况,进行动画的播放状态的监听, 通过监听器可以监测:动画的开始、循环、停止; 当动画还在播放的时候,如果再次设置控件的动画,那么当前的动画将会终止;

关于动画的平滑

Android系统,播放补间动画时,根据时间,起始状态、结束状态,生成动画效果 插值器 interpolator: Android系统根据插值器,在每一个等分的时间中,来设置不同的数值

组合变化

translate + scale 在 中,写入多个动画效果就可以将多种效果同时组合在一起播放。 如果希望动画是串行执行,那么后续动画的起始播放时间,需要延后!!! 补间动画的 set 最终相当于线程池,内部的每一个动画效果实际上是由一个线程执行的,所有即使一个效果无限循环,其他效果也能够执行。

补间动画的重点

!!! 任何动画的操作都不会影响实际控件的状态。因为实际上补间动画只是把控件的外观进行了各种处理,相当于控件还在原来的位置,还是原来的尺寸 尝试 translate + rotate 就可以重现控件状态。 补间动画 通过 AnimationUtils.loadAnimation 进行加载的。给控件 View startAnimation(Animation) 就可以执行控件的动画了。

关于动画的接口

动画播放的时候是有状态了,例如 开始动画、动画结束
AnimationListener 包含动画三种状态的回调:

onAnimationStart 动画开始执行 onAnimationEnd 动画执行完成 onAnimationRepeat 动画重复执行。

几种动画效果

xml文件
res/anim/

旋转:


移动:

    

缩放:

  
    

set集合




    
    
    
    

java 代码文件

public void btnRotateClick(View view) {
        //图片旋转
        Animation animation = AnimationUtils.loadAnimation(this, R.anim.anim_rotate);
        animation.setRepeatMode(Animation.INFINITE);

        //设置插值器 平滑旋转
        animation.setInterpolator(new LinearInterpolator());

        view.startAnimation(animation);


    }

    public void btMoveInterpolator(View view) {
        //带有插值器的移动
        Animation animation = AnimationUtils.loadAnimation(this, R.anim.anim_move);
        animation.setDuration(1000);
//        animation.setInterpolator(new OvershootInterpolator(20));
        animation.setInterpolator(new SimpleInterpolator());

        view.startAnimation(animation);
    }

    public void btnScale(View view) {
        ImageView imageView = (ImageView) findViewById(R.id.image_view);
        if (imageView != null) {
            Animation animation = AnimationUtils.loadAnimation(this, R.anim.anim_heartbeat);
            animation.setDuration(1000);
            AnimationSet animationSet = (AnimationSet) animation;
            List animations = animationSet.getAnimations();
            Animation anim = animations.get(0);

            //设置第一次执行完成之后, 循环播放的次数
            anim.setRepeatMode(Animation.REVERSE);
            anim.setRepeatCount(Animation.INFINITE);
            imageView.startAnimation(animation);
        }
    }

动画的监听

设置动画监听: 当动画开始, 完成, 重复时, 进行回调
        animation.setAnimationListener(this);

 //////////////Animaition监听/////start/////////////
   @Override
    public void onAnimationStart(Animation animation) {

    }

    @Override
    public void onAnimationEnd(Animation animation) {
        tvInc.setVisibility(View.INVISIBLE);

        tvZan.setText("赞" + zanCount);
    }

    @Override
    public void onAnimationRepeat(Animation animation) {

    }
    //////////////Animaition监听///////end/////////////

逐帧动画

!!! 逐帧动画是一个 drawable 可以认为是一个图片;和 shape 相似都是用 xml 写出来的。 当中,从 xml 顺序加载图片,最上面的 最先显示。 可以指定 oneshoot 属性,控制动画是否只播放一次。如果为 true,那么只播放一次,即使播放完成, 如果不进行stop的话,依然是 running的状态。代表直接start()是不会执行的,只有stop之后才可以重新start

逐帧动画的使用

准备图片资源 在drawable中编写 xml,指定每一帧的显示图片内容 ImageView 或者 其他View 的background属性,指定资源,方式:@drawable/名称 代码获取ImageView ,并且获取到 background ,检查是否是 AnimationDrawable ,进行强制类型转换 AnimationDrawable start(), stop(); 进行播放的控制 start() 不支持继续播放,每次从头开始。

应用场景

重复的,有动画效果的提示性内容,例如:京东客户端下拉刷新的时候“快递小哥”的动画 一些小的动画,不能够使用补间动画的情况,或者显示现实世界中的人物、动画的动态效果。 主要是配合一些事件的操作,如下拉刷新、圆圈进度条的处理

代码示例





    
         .....
    

    public void btnPlayFrame(View view) {
        //TODO: 播放动画
        //1. 因为逐帧动画是图片, 所以要从ImageView中取出来, 才能进行控制
        ImageView imageGift = (ImageView) findViewById(R.id.image_gift);
        //获取src属性
        Drawable drawable = imageGift.getDrawable();

        //shape -> ShapeDrawable
        //animation-list -> AnimationDrawable
        if (drawable != null && drawable instanceof AnimationDrawable) {
            //2. 播放动画
            AnimationDrawable animationDrawable = (AnimationDrawable) drawable;
            animationDrawable.start();
        }



//        imageGift.setImageDrawable();
    }


    public void btnStopFrame(View view) {
        //TODO: 停止动画
        //1. 获取图像 逐帧动画

        ImageView imageGift = (ImageView) findViewById(R.id.image_gift);
        Drawable drawable = imageGift.getDrawable();
        if (drawable != null && drawable instanceof AnimationDrawable) {
            AnimationDrawable animationDrawable = (AnimationDrawable) drawable;

            //Stop会将动画暂停, 但是下一次, start的时候, 会从头开始播放
            animationDrawable.stop();

            //Gif 如何显示: GifDrawable库  WebView

        }
    }

属性动画

属性动画定义在 res/animator/ 这个资源目录下; 属性动画:实现按时间进行控件属性的变化; 实际改变控件的属性,整个布局重新排版,而且不会还原。

objectAnimator标记

能够以动画的方式修改任意对象的属性; 能够通过 setXxxx 这种方法的自动调用,来实现对属性“xxxx” 来进行修改; 这个标记可以通过 指定属性的名称,来进行设置。

原理

这里写图片描述

执行原理<喎"http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4NCkFuaW1hdG9yIM2ouf0geG1sIMC0vNPU2KOsu/HIodDo0qrQ3rjEtcTK9NDUtcTD+7PGoaLA4NDNoaLK/da1o7sgQW5pbWF0b3JJbmZsYXRvciDAtLzT1Nh4bWwsINauuvPJ6NbDwcsgc2V0VGFyZ2V0KE9iamVjdCkgo6zWuLao0OjSqtDeuMTK9NDUtcTE2sjdtcS21M/zo7sgzai5/b2ryvTQ1LXEw/uzxteqzqogSmF2YUJlYW4gyvTQ1Le9t6jJ6NbDw/zD+7nm1PKjusr00NTD+8rX19bEuLTz0LSjrMeww+bM7bzTIHNldKOswP3I5yBsZWZ0yvTQ1KOsxMfDtL7Nu+HJ+rPJIHNldExlZnQoyv3WtcDg0M0pIL340NC3tMnko6yy6dXS1ri2qLbUz/PW0MrHt/Gw/Lqs1eK49re9t6ijrMjnufuw/Lqso6y+zb/J0tSwtNXV1ri2qLXEyrG85ChkdXJhdGlvbikgvfjQ0CB2YWx1ZUZyb20gtb0gdmFsdWVUbyDV4sG91rXWrrzktcS9+NDQtq/MrLXEyejWw6GjDQo8aDMgaWQ9"实现步骤">实现步骤 准备属性动画的XML动画资源; 准备需要播放动画的对象; 加载属性动画的 XML 设置动画要修改的对象 修改的属性名称,一定是 Java类文件中的 public void setXxxxx(… xxx) 的方法的 xxxx 这个属性,首字母小写

属性动画的Target的设置

比较常见的是 View 修改的属性都是 color, dimension, int, float 属性动画还可以指定非 View的对象。官方使用采用的自定义的Object,然后再Object setXxxx() 内部来实现更强大功能。
这里写图片描述

动画执行序列 < set>

set 标签可以 通过 ordering属性进行设置,内部的动画是否在一起执行
sequentially 串行执行,一个执行完,在执行另外的一个,不要有无限重复的,因为后边的没法执行了
together 并行一起执行

V4包动画支持

ViewCompat 支持 设置View的状态,例如 ViewCompat.setScaleX(View, float) 就是缩放控件水平方向的尺寸;
ViewPropertyAnimatorCompat 支持 实现低版本手机的属性动画功能,
ViewCompat.animate(View) 为View创建一个属性动画对象

动画与事件的配合

ScrollView 的 onTouch 中的 MOVE 事件可以和控件的隐藏显示配合
ListView OnScrollListener 可以检测ListView的滚动,滚动的过程中可以实现图片,标题的缩放

代码实例

res/animator/

 

    

    

    

java

    public void btnPropertyMove(View view) {
        //属性动画的加载
        //1. 加载器 加载xml文件
        Animator animator = AnimatorInflater.loadAnimator(this,
                R.animator.animator_move);
        //2. 将需要修改的对象传递给属性动画
        animator.setTarget(mTextView);
        //3. 动画的播放

        animator.start();
    }

    public void btnPropertyColor(View view) {
        Animator animator = AnimatorInflater.loadAnimator(this, R.animator.animator_color);
        animator.setTarget(mTextView);
        animator.start();
    }

    public void btnPropertyTextSize(View view) {
        Animator animator = AnimatorInflater.loadAnimator(this, R.animator.animator_textsize);
        animator.setTarget(mTextView);
        animator.start();


    }

    public void btnPropertyCustom(View view) {
        //自定义对象的属性修改

        //1. 自定义类对象: 确认属性名
        TextShower shower = new TextShower(mTextView);
        //2. 加载xml或者写代码
        Animator animator = AnimatorInflater.loadAnimator(this, R.animator.anmiator_text_show);
        //3. 设置目标
        animator.setTarget(shower);
        animator.start();



    }

    public void btnPropertyCode(View view) {
        //代码形式的属性动画
        //所有的属性的数值,如果是位置那么以像素为单位
//     ObjectAnimator.ofFloat(mTextView, "translationX", 0, 200).setDuration(2000).start();
        //利用set 可以实现多个属性同时修改

        AnimatorSet set = new AnimatorSet();
        ObjectAnimator animator1 = ObjectAnimator.ofFloat(mTextView, "translationX", 0, 400).setDuration(2000);
        ObjectAnimator animator2 = ObjectAnimator.ofFloat(mTextView, "rotation", 0, 360).setDuration(200);
        set.playTogether(animator1, animator2);
        set.start();

    }
相关文章
最新文章
热点推荐