IT教程 ·

进阶之路 | 巧妙的Animation之旅

文本相似性算法实现(二)-分组及分句热度统计

媒介

本文已收录到我的Github个人博客,迎接大佬们莅临舍下:

进修清单:

  • 动画的品种
  • 自定义View动画
  • View动画的特别运用场景
  • 属性动画
  • 运用动画的注重事项

一.为何要进修Animation?

笔者在之前中,说起View滑动的七种体式格局的时刻简朴说到Animation,想必看过的读者们已对Animation有一个简朴的印象。

动画,关于一个APP来讲非常重要,如今市面上运用的用户比较多的APP,无一不是采纳了种种丰富多彩的动画结果;在运用中擅长运用动画,不仅让APP的体验更上一层楼,还能紧紧捉住用户的心!

而作为开发者的我们,肯定要对动画有肯定深度的相识,在一样平常的进修或许事情中多多尝试动画,以进步运用程序的雅观度和易用性!

什么,你不信动画很重要....反手甩你一个对照视频:

进阶之路 | 巧妙的Animation之旅 IT教程 第1张

二.中心学问点归结

2.1 View动画

View动画(视图动画)分为两部分:

  • 补间动画
  • 帧动画

2.1.1 补间动画

1 基础学问

Q1:重要的变更结果

称号 标签 子类 结果
平挪动画 translate TranslateAnimation 挪动View
缩放动画 scale ScaleAnimation 放大或减少View
扭转动画 rotate RotateAnimation 扭转View
通明度动画 alpha AlphaAnimation 转变View的通明度

注重:View动画的View挪动只是视觉结果,并不能真正的转变view的位置。

Q2:动画的建立

关于View动画发起采纳XML来定义,由于XML可读性更好

建立要领一:经由历程XML定义

  • XML文件建立在res/anim/
  • 根节点set,子节点translatescalerotatealpha,离别对应四种View动画:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="true"
    android:fillAfter="true">
    
    <translate
        android:fromXDelta="float"
        android:toXDelta="float"
        android:fromYDelta="float"
        android:toYDelta="float"/>
     <scale
        android:fromXScale="float"
        android:toXScale="float"
        android:fromYScale="float"
        android:toYScale="float"
        android:pivotX="float"
        android:pivotY="float"/>    
     <rotate
        android:fromDegrees="float"
        android:toDegrees="float"
        android:pivotY="float"
        android:pivotX="float"/>
    <alpha 
        android:fromAlpha="float"
        android:toAlpha="float"/>

</set>

接下来离别诠释各个节点下属性寄义:

A.set:示意动画鸠合,对应AnimationSet

  • interpolator:示意动画鸠合所采纳的插值器,影响动画的速率。能够不指定,默许是accelerate_decelerate_interpolate(加快减速插值器)。下文属性动画会细致引见插值器的相干学问。
  • shareInterpolator:示意鸠合中的动画是不是和鸠合同享一个插值器。假如鸠合不指定插值器, 那末子动画就须要零丁制订所需的插值器或许运用默许值。
  • fillAfter:示意动画完毕时是不是坚持动画完毕时的状况

B.translate:示意平挪动画,对应TranslateAnimation

  • android:fromXDelta:动画肇端时X坐标上的位置。
  • android:toXDelta:动画完毕时X坐标上的位置。
  • android:fromYDelta:动画肇端时Y坐标上的位置。
  • android:toYDelta:动画完毕时Y坐标上的位置。

注重:以上四个属性以及背面几个相似属性的取值多是数值、百分数、百分数p,各自寄义是:

  • 50:以View左上角为原点沿坐标轴正方向偏移50px。
  • 50%:以View左上角为原点沿坐标轴正方向偏移View宽/高度的50%。
  • 50%p:以View左上角为原点沿坐标轴正方向偏移父(parent)控件宽/高度的50%。区分如图:

进阶之路 | 巧妙的Animation之旅 IT教程 第2张

C.scale:示意缩放动画,对应ScaleAnimation

  • fromXScale:动画肇端时X坐标上的伸缩尺寸
  • toXScale:动画完毕时X坐标上的伸缩尺寸
  • fromYScale:动画肇端时Y坐标上的伸缩尺寸
  • toYScale:属性为动画完毕时Y坐标上的伸缩尺寸

以上四个属性值的值寄义:

  • 值=0.0 :示意压缩到没有
  • 值<1.0 :示意压缩
  • 值=1.0 :示意无伸缩
  • 值>1.0 :示意放大
  • pivotX:动画相干于物件的X坐标的入手下手位置
  • pivotY:动画相干于物件的Y坐标的入手下手位置

以上两个属性值示意缩放的轴点:从0%-100%中取值。

D.rotate:示意扭转动画,对应RotateAnimation类。

  • fromDegrees:动画肇端时物件的角度 (0度指X轴正方向地点方向)
  • toDegrees:动画完毕时物件扭转的角度

以上两个属性配合肯定扭转方向,原则是:当角度(to-from)为数时示意逆时针扭转,反之。

  • pivotY:动画扭转的轴点的X坐标
  • pivotX:动画扭转的轴点的Y坐标

E.alpha:示意通明度动画,对应AlphaAnimation

  • fromAlpha:动画肇端时通明度
  • toAlpha:动画完毕时通明度

以上两个属性值:从0-1中取值。注重:

  • 值=0.0 :示意完全通明
  • 值=1.0 :示意完全不通明

以上四类补间动画除了各自的特有属性外,它们的共有属性有:

进阶之路 | 巧妙的Animation之旅 IT教程 第3张

XML声明好以后,接下来只要在代码中startAnimation(animation)入手下手动画即可,代码以下:

Animation animation = AnimationUtils.loadAnimation(this, R.anim.XXX);
mView.startAnimation(animation);

同时,可经由历程Animation的setAnimationListener(new AnimationListener(){...})给动画增加历程监听,如许在动画入手下手、完毕和每一次轮回时都可在回调要领中监听到。接口代码以下:

public static interface AnimationListener {
        //动画入手下手        
        void onAnimationStart(Animator animation);
        //动画完毕
        void onAnimationEnd(Animator animation);
        //动画反复
        void onAnimationRepeat(Animator animation);
    }

建立要领二: 经由历程Java代码动态建立

  • 详细步骤:
    1. 建立TranslateAnimationRotateAnimationScaleAnimationAlphaAnimation对象。
    2. 设置建立的动画对象的属性,如动画实行时候、耽误时候、肇端位置、完毕位置等
    3. 经由历程View.startAnimation()要领开启动画
    4. 可经由历程Animation.setAnimationListener()设置动画的监听器

Q3:综合实例

A1:平移

//法一:xml定义
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
           android:duration="2000"
           android:fromXDelta="0"
           android:fromYDelta="0"
           android:toXDelta="100%"
           android:toYDelta="100%">
</translate>

//在MainActivity中挪用
  Animation translateAnim = AnimationUtils.loadAnimation(this, R.anim.view_anim_translate);
    mImageView.startAnimation(translateAnim);
//法二:java代码建立 RELATIVE_TO_SELF示意相对本身View
TranslateAnimation translateAnimation = new TranslateAnimation(
            Animation.RELATIVE_TO_SELF, 0,
            Animation.RELATIVE_TO_SELF, 1,
            Animation.RELATIVE_TO_SELF, 0,
            Animation.RELATIVE_TO_SELF, 1);
    translateAnimation.setDuration(2000);
    mImageView.startAnimation(translateAnimation);
}

进阶之路 | 巧妙的Animation之旅 IT教程 第4张

A2:缩放

//法一:xml定义
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
       android:duration="2000"
       android:fromXScale="1.0"
       android:fromYScale="1.0"
       android:pivotX="50%"
       android:pivotY="50%"
       android:toXScale="0.5"
       android:toYScale="0.5">
</scale>

//在MainActivity中挪用
   Animation scaleAnim = AnimationUtils.loadAnimation(this, R.anim.view_anim_scale);
    mImage.startAnimation(scaleAnim);
//法二:java代码建立
ScaleAnimation scaleAnimation = new ScaleAnimation(
            1, 0.5f,
            1, 0.5f,
            Animation.RELATIVE_TO_SELF, 0.5f,
            Animation.RELATIVE_TO_SELF, 0.5f);
    scaleAnimation.setDuration(2000);
    mImageView.startAnimation(scaleAnimation);

进阶之路 | 巧妙的Animation之旅 IT教程 第5张

A3: 扭转

//法一:xml定义
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="2000"
        android:fillAfter="true"
        android:fromDegrees="0"
        android:toDegrees="360"
        android:pivotX="50%"
        android:pivotY="50%">
</rotate>

//在MainActivity中挪用
Animation rotateAnim = AnimationUtils.loadAnimation(this, R.anim.view_anim_rotate);
    mImageView.startAnimation(rotateAnim);
//法二:java代码建立
RotateAnimation rotateAnimation = new RotateAnimation(
            0, 360,
            Animation.RELATIVE_TO_SELF, 0.5f,
            Animation.RELATIVE_TO_SELF, 0.5f);
    rotateAnimation.setDuration(2000);
    mImageView.startAnimation(rotateAnimation);

结果:图片在2s内以图片中心为轴点,顺时针扭转360°,即完全转一圈。

A4:通明度:

//法一:xml定义
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
       android:duration="2000"
       android:fromAlpha="1.0"
       android:toAlpha="0">
</alpha>

//在MainActivity中挪用
    Animation alphaAnim = AnimationUtils.loadAnimation(this, R.anim.view_anim_alpha);
    mImageView.startAnimation(alphaAnim);
//法二:java代码建立
AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
    alphaAnimation.setDuration(2000);
    mImageView.startAnimation(alphaAnimation);

结果:图片在2s内从有到无。

A5:动画鸠合:

//法一:xml定义
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="true" >
    
    <translate
        android:duration="2000"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="100%"
        android:toYDelta="100%"> />
    <scale
       android:duration="2000"
       android:fromXScale="1.0"
       android:fromYScale="1.0"
       android:pivotX="50%"
       android:pivotY="50%"
       android:toXScale="0.5"
       android:toYScale="0.5" /> 
    <rotate
        android:duration="2000"
        android:fromDegrees="0"
        android:toDegrees="360"
        android:pivotX="50%"
        android:pivotY="50%"/>
     <alpha
       android:duration="2000"
       android:fromAlpha="1.0"
       android:toAlpha="0"/>   
</set>

//在MainActivity中挪用
    Animation setAnim = AnimationUtils.loadAnimation(this, R.anim.view_anim_set);
    mImageView.startAnimation(setAnim);

结果:以上四种动画结果的叠加。图片在2s内边向右下角挪动、边减少、边扭转、边下降通明度至消逝。

2 自定义动画

现实项目中以上几种动画并不能满足我们的需求,这时候就须要自定义补间动画

  • 步骤:

    1.继续Animation

    2.重写initialize()--->用于初始化

    3.重写applyTransformation()--->用于举行矩阵变更

    常常须要借助Camera来简化矩阵变更

  • 实例:、
3 特别运用场景

View动画除了可作用在某个View对象上, 还能够用在特别的场景,比方:

  • 掌握ViewGroup子View进场结果
  • Activity切换结果

    接下来将顺次引见:

A1:子View进场动画

  • 经常使用场景:ListViewGridViewRecyclerView
  • 对应类:LayoutAnimation
  • XML文件建立在res/anim/
  • 根节点layoutAnimation,经常使用属性:
layoutAnimation 
    |- delay="float"
    |- animationOrder="[normal|reverse | random]"
    |- animation="[@anim/res_id]"

delay:示意子元素入手下手动画的耽误时候

比方,子元素入场动画的时候周期是300ms,那末该属性值=0.5就示意每个子元素都须要耽误150ms才播放入场动画。

animationOrder :示意子元素动画的播放次序。可选形式:normal (平常次序)、random(随机次序)、reverse(倒序)。

animation :为子元素指定详细的入场动画。

  • 建立要领:

法一:xml定义,分两步

step1:定义layoutAnimation动画

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

// res/anim/anim_item.xml    结果:子项从右侧进入
<set 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:shareInterpolator="true"
    android:interpolator="@android:anim/accelerate_interpolator">
    <alpha
        android:fromAlpha="0"
        android:toAlpha="1" />
    <translate
        android:fromXDelta="100%"
        android:toXDelta="0"
        />
</set>

step2:为ViewGroup设置android:layoutAnimation属性, 这里假设为Listview


//activity_main.xml
<ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layoutAnimation="@anim/anim_layout"/>

法二:java代码建立,经由历程LayoutAnimation类绑定



// res/anim/anim_item.xml 
<set 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:shareInterpolator="true"
    android:interpolator="@android:anim/accelerate_interpolator">
    <alpha
        android:fromAlpha="0"
        android:toAlpha="1" />
    <translate
        android:fromXDelta="100%"
        android:toXDelta="0"
        />
</set>
            
 //main.java 
//和上述xml定义要领的结果雷同
Animation animation = AnimationUtils.loadLayoutAnimation(this, R.anim.anim_item);
LayoutAnimationController controller = new LayoutAnimationController(animation);//对应android:animation属性
controller.setDelay(0.5);//对应android:delay属性    
controller.setOrder(LayoutAnimationController.ORDER_NORMAL); //对应android:animationOrder属性
listView.setLayoutAnimation(controller);//对应android:layoutAnimation属性

A2:Activity的切换结果

  • 该xml文件建立在res/anim/
  • Activity默许是有切换结果的,若须要自定义切换结果,须要用到overridePendingTransition(int inAnim, int outAnim)要领
  • 参数寄义:(进入的Activity所需举行的动画id,退出的Activity所需举行的动画id)
  • 该要领挪用在startActivity()finish()才见效。比方:
startActivity(intent);
overridePendingTransition(R.anim.enter_anim, R.anim.exit_anim);
  • 补充实例:感兴趣的读者能够相识下:

2.1.2 帧动画

  • 帧动画也是View动画的一种,它会依据次序播放一组预先定义好的图片。对应类AnimationDrawable
  • 个中AnimationDrawable,笔者在的文章末端处也提到过。

Q1:帧动画的建立

A1:经由历程xml定义:

  • 该xml文件建立在res/drawable/ 下。
  • 根节点animation-list,属性android:oneshot示意是不是实行一次;子节点item 下可设置轮播的图片资本id和延续时候。比方:
<?xml version="1.0" encoding="utf-8"?>
<animation-list  xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item android:drawable="@drawable/xxx1" android:duration="500"/>
    <item android:drawable="@drawable/xxx2" android:duration="500"/>
    <item android:drawable="@drawable/xxx3" android:duration="500"/>
    <item android:drawable="@drawable/xxx4" android:duration="500"/>
</animation-list>

XML声明好以后,将它作为View的背景并经由历程AnimationDrawable来播放即可。代码以下:

mView.setBackgroundResource(R.drawable.XXX);
AnimationDrawable animationDrawable = (AnimationDrawable)mView.getBackground();
animationDrawable.start();

A2:经由历程Java代码动态建立

//和上述xml定义要领的结果雷同
AnimationDrawable ad = new AnimationDrawable();//1.建立AnimationDrawable对象
    for (int i = 0; i < 4; i++) {//2.增加Drawable对象及其延续时候
        Drawable drawable = getResources().getDrawable(getResources().getIdentifier("xxx" + i, "drawable", getPackageName()));
        ad.addFrame(drawable, 500);
    }
    ad.setOneShot(false);//3.设置是不是实行一次
    mView.setBackgroundResource(ad);//4.将帧动画作为view背景
    ad.start();//5.播放动画
  • 注重:运用帧动画要注重不能运用尺寸过大的图片,不然轻易形成OOM( 内存溢出)
  • 想要更进一步相识帧动画的读者,能够看一下这篇文章:

2.2 属性动画

2.2.1 插值器和估值器

用处:属性动画中的插值器和估值器能够完成非匀速动画

1 插值器(Interpolator)
  • 作用:依据时候流逝的百分比计算出当前属性值转变的百分比。肯定了动画结果变化的形式,如匀速变化、加快变化、减速变化等等。
  • 经常使用的体系内置插值器:

    a.线性插值器(LinearInterpolator):匀速动画

    b.加快减速插值器(AccelerateDecelerateInterpolator):动画两端慢中心快

    c.减速插值器(DecelerateInterpolator):动画越来越慢

  • 可针对的对象:

    a.View动画:插值器对应的属性是android:interpolator

    b.属性动画:是完成非匀速动画的重要手腕。

  • 自定义插值器要领:完成 Interpolator / TimeInterpolator接口 ,然后复写getInterpolation()
  • 补间动画完成 Interpolator接口、属性动画完成TimeInterpolator接口。
  • TimeInterpolator接口是属性动画中新增的,用于兼容Interpolator接口。

进阶之路 | 巧妙的Animation之旅 IT教程 第6张

2 范例估值器(TypeEvaluator)
  • 作用:依据当前属性转变的百分比计算出转变后的属性值
  • 经常使用的体系内置的估值器:
  • 整型估值器(IntEvaluator)
  • 浮点型估值器(FloatEvaluator)
  • Color属性估值器(ArgbEvaluator)
  • 仅针关于属性动画,View动画不须要范例估值器。是属性动画完成非匀速动画的重要手腕。
  • 自定义估值器要领:完成TypeEvaluator接口,然后复写evaluate()

限于篇幅,本篇文章未引见自定义插值器和估值器的实例,想要相识的读者,能够看下这篇文章:

2.2.2 属性动画与View动画异同

View动画 属性动画
完成体式格局 经由历程不停图形变更 经由历程动态转变对象属性
作用对象 View 任何对象,以至没有对象
寄存位置 anim animator
状况变化 未真正转变View位置 真正转变View位置

2.2.3 完成体式格局

1 经由历程XML

res/animator/下可建立属性动画的XML文件。个中,根节点set对应AnimatorSet类,子节点objectAnimator对应ObjectAnimator类、animator对应ValueAnimator类。经常使用属性:

//animator/XX.xml
<set
  android:ordering=["together" | "sequentially"]>

    <objectAnimator
        android:propertyName="string"
        android:duration="int"
        android:valueFrom="float | int | color"
        android:valueTo="float | int | color"
        android:startOffset="int"
        android:repeatCount="int"
        android:repeatMode=["repeat" | "reverse"]
        android:valueType=["intType" | "floatType"]/>

    <animator
        android:duration="int"
        android:valueFrom="float | int | color"
        android:valueTo="float | int | color"
        android:startOffset="int"
        android:repeatCount="int"
        android:repeatMode=["repeat" | "reverse"]
        android:valueType=["intType" | "floatType"]/>

    <set>
        ...
    </set>
</set>

//java
AnimatorSet set= AnimatorInflater.loadAnimator(myContext,R.anim.xxx);
set.setTarget(mBtn);
set.start();

起首引见set标签下的经常使用属性:

  • ordering:设置动画的时序关联。可选值:
  • together:默许值。示意动画鸠合中的子动画同时播放
  • equentially:示意动画鸠合中的子动画依据誊写的先后次序顺次播放

接下来详细引见属性动画的完成体式格局:

A.经由历程ObjectAnimator完成属性动画

  • 道理:经由历程直接对对象object)的属性值举行转变操纵,从而完成动画结果。
  • 对应根节点objectAnimator
  • 经常使用属性引见:
  • propertyName:属性动画作用的属性称号
  • duration: 动画延续时长
  • startOffset:设置动画实行之前的守候时长
  • repeatCount:动画反复实行的次数;默许为0,示意只播放一次。设置为-1或infinite,示意无穷反复。
  • repeatMode:动画反复实行的形式。可选值:

    a.restart:示意一连反复,为默许值。

    b.reverse :示意逆向反复

  • valueFrom:动画初始值
  • valueTo:动画完毕值
  • valueType:示意propertyName指定的属性值范例。可选值:

    a.intType :以上两个value属性值为整型。

    b.floatType:即以上两个value属性值为浮点型,为默许值。

    c.color:若propertyNamecolor,则无需设置该属性。

B.经由历程ValueAnimator完成属性动画

  • 道理:经由历程不停掌握(value)的变化,再不停手动赋给对象的属性,从而完成动画结果。

ObjectAnimatorValueAnimator类的区分:

  • ValueAnimator 类是先转变值,然后手动赋值给对象的属性从而完成动画;是间接对对象属性举行操纵
  • ObjectAnimator 类是先转变值,然后自动赋值给对象的属性从而完成动画;是直接对对象属性举行操纵
  • 对应根节点animator
  • 经常使用属性比objectAnimator标签少一个android:propertyName属性,其他雷同
2 经由历程JAVA

现实开发中发起用JAVA的体式格局来完成属性动画,缘由:

  • 经由历程代码来完成比较简朴
  • 许多时刻属性的肇端值没法提早肯定

A.ObjectAnimator

注重:这里ObjectAnimator 作用的属性必需有set要领

get要领可选;当动画没有设置初始值的时刻,get必需存在)

  • 要领:
//第一个参数是对象,第二个是对象的属性名字,第3个是值的变化,能够是ofFloat或许是ofInt,依据参数的范例直接写
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(tv,"alpha",1,0,1); 
//设置延续时候
objectAnimator.setDuration(2000);
 objectAnimator.start();
  • 源码剖析:
//ofFloat直接返还一个 ObjectAnimator对象
public static ObjectAnimator ofFloat (Object target,String propertyName,float... values){
            ObjectAnimator anim=new ObjectAnimator (target,propertyName);
            anim.setFloatValues(values);
        return anim;
}

B.ValueAnimator

  • ValueAnimator不供应任何动画结果,更像一个数值发生器,用来发生有肯定规律的数字,从而让挪用者掌握动画的完成历程。
  • 平常在AnimatorUpdateListener/AnimatorListenerAdapter(在下文会细致引见)中监听数值的变化,而完成动画的变更

测试实例:

  //完成色彩的渐变
    ValueAnimator valueAnimator = ValueAnimator.ofArgb(0xFFFF5454, 0xFF5DDE5D, 0xFF5DBEDE);
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            int color = (int) animation.getAnimatedValue();
            button.setBackgroundColor(color);
        }
    });
    valueAnimator.setDuration(2000);
    //记得start
    valueAnimator.start();

C.组合动画

C1.AnimatorSet

能够完成有先后次序的组合动画

  • 重点要领:
  • play:传入一个 Animator 对象 ,会返回一个AnimatorSet.Builder的实例
  • Builder中有4个要领:

    a.after(Animator):将现有动画插进去到传入的动画以后实行

    b.before(Animator):将现有动画插进去到传入的动画之前实行

    c.with(Animator):将现有动画和传入的动画同时实行。

    d.after(Long):将现有动画耽误指定毫秒后实行。

进阶之路 | 巧妙的Animation之旅 IT教程 第7张

  • 实例运用:
ObjectAnimator alphaAnimator =ObjectAnimator.ofFloat(tv, "alpha", 1, 0, 1);
ObjectAnimator rotateAnimator =ObjectAnimator.ofFloat(tv, "rotation", 0, 360, 0);
rotateAnimator.setDuration(15000);
ObjectAnimator scaleAnimator =ObjectAnimator.ofFloat(tv, "scaleX", 1, 2, 1);
ObjectAnimator translateAnimator =ObjectAnimator.ofFloat(tv, "translationX", 0, 100, 0);

AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(alphaAnimator)
.with(rotateAnimator)
.after(scaleAnimator)
.before(translateAnimator);
animatorSet.setDuration(2000).start();

进阶之路 | 巧妙的Animation之旅 IT教程 第8张

C2:PropertyValuesHolder

能够完成同时实行的组合动画

  • 实例运用:
//新建动画类 
PropertyValuesHolder valuesHolder1=PropertyValuesHolder.ofFloat("scaleX",1.0f,1.5f);
PropertyValuesHolder valuesHolder2=PropertyValuesHolder.ofFloat("rotationX",0f,90.0f);
//新建ObjectAnimator
ObjectAnimator animator=ObjectAnimator.ofPropertyValuesHolder(view,valuesHolder1,valuesHolder2);
//开启动画 
animator.setDuration(200).start();

2.2.4 监听器

属性动画重要运用两个接口:AnimatorUpdateListener&AnimatorListener来监听动画的播放历程。

  • AnimatorListener:监听动画的入手下手、完毕、作废以及反复播放。以下:
public static interface AnimatorListener {
    void onAnimationStart(Animator animation); //动画入手下手
    void onAnimationEnd(Animator animation); //动画完毕
    void onAnimationCancel(Animator animation); //动画作废
    void onAnimationRepeat(Animator animation); //动画反复播放
}

为轻易开发,体系供应了AnimatorListenerAdapter类,它是AnimatorListener的适配器,云云可有挑选复写上述四个要领。

  • AnimatorUpdateListener:监听全部动画历程。每播放一帧,onAnimationUpdate()就会被挪用一次,以下:
public interface AnimatorUpdateListener {
  void onAnimationUpdate(ValueAnimator var1);//在属性动画的属性值变化是回调。
}

2.2.5 对恣意属性做动画

  • 需满足的前提:
  • 对象必需供应set要领,若未通报初始值给动画,还需供应get要领(由于体系须要去取初始值)
  • set要领对属性所做的转变必需能经由历程某种体式格局反应出来(比方:UI结果转变)
  • 解决要领:

    A.给对象加上getset要领

这个要领平常不可行,由于大多数的时刻,我们没有权限

​ B.用包装类的体式格局,间接供应getset要领

实例:

class MyView{
private View mTarget;
private MyView (View view){
mTarget =view;
}
    
//属性的get要领
public int getWidth(){
return mTarget.getLayoutParams().width;
}

//属性的set要领
public void setWidth(int width){
mTarget.getLayoutParams().width=width;
mTarget.requestLayout();
}
}
MyView myView = new MyView(mButton);
ObjectAnimator.ofInt(myView, "width", 500).setDuration(500).start();

C.用ValueAnimator监听动画历程,本身转变属性

测试实例:

    /**
     * 转变对象的宽度
     * @param target 对象
     * @param start 肇端值
     * @param end 目标值
     */
    private void performAnimate(final View target, final int start, final int end) {
        ValueAnimator valueAnimator = ValueAnimator.ofInt(1, 100);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                //持有一个IntEvaluator对象,轻易下面估值的时刻运用
                IntEvaluator evaluator = new IntEvaluator();
                //获得当前动画的进度值
                float fraction = animation.getAnimatedFraction();
                //挪用整型估值器,经由历程比例计算出宽度,然后设给Btn
                target.getLayoutParams().width = evaluator.evaluate(fraction, start, end);
                target.requestLayout();
            }
        });
        valueAnimator.setDuration(5000).start();
    }

2.2.6 事情道理

  • 整体思绪:在肯定时候距离内,经由历程不停对值举行转变,并不停将该值赋给对象的属性,从而完成该对象在该属性上的动画结果。

详细体如今 :

  • 建立属性动画时,若未设初值,则体系会经由历程该属性的get()要领猎取初始值。故属性动画请求必需供应属性的get()要领
  • 在动画播放的历程当中,应用时候插值器和范例估值器猎取转变后的属性值
  • 将转变后的属性值经由历程set()要领设置到对象中。故属性动画请求必需供应属性的set()要领
  • 详细流程:

get/set要领是经由历程反射挪用的,笔者将带你深切属性动画的源码,探究其缘由:

三.注重事项

祝贺你!已看完了前面的文章,相信你对Animation已有肯定深度的相识!

在运用历程当中,也有一些事项是须要我们注重的:

  • OOM问题

这个问题重要出如今帧动画中,当图片数目较多且图片较大时易涌现OOM,所以一样平常开发中只管防止运用帧动画

  • 内存走漏
  • 属性动画中有一类无穷轮回的动画(repeatCount=-1),这类动画须要在Activity退出时实时住手,不然致使Activity没法开释形成内存走漏
  • View动画不存在这个问题
  • View动画的问题

View动画是对View的影象做动画,不是真正转变View的状况,有时刻涌现动画完成后View没法隐蔽的征象(setVisibility(View.GONE)失效),须要挪用view.clearAnimation()消灭View动画

  • 不要运用px

在举行动画的历程当中,只管运用dp,运用px会致使在差别的装备上有差别的结果

想要相识详细缘由的读者,笔者给您引荐一篇文章:

  • 动画元素的交互

Android3.0以后,属性动画的单击事宜触发位置为挪动后的位置,然则View动画仍在原位置

  • 硬件加快

Android4.0入手下手默许开启硬件加快

假如文章对您有一点协助的话,愿望您能点一下赞,您的点赞,是我行进的动力

本文参考链接:

  • 《Andorid 开发艺术探究》
  • 《Android 进阶之光》

JMeter-完成批量的接口测试

参与评论