一、概述

  属性动画可以作用在View的属性上,对属性进行修改,而且不要求对应的属性一定是有显示效果的。

二、属性动画的实现方式

  1、基础的类Animator

  Animator是一个抽象类,是属性动画的基础类。不直接使用该类。

  2、ObjectAnimator,继承自ValueAnimator

  使用起来比较方便的是ObjectAnimator,可以使用ObjectAnimator直接指定需要修改的view,要修改的属性,值的变化范围。  

  ObjectAnimator.ofFloat(view, "rotationX", 0.0F, 360.0F)
.setDuration(500)
.start();

  通过上面的代码,就可以让View动起来,十分方便。ObjectAnimator不止有ofFloat方法,还有ofInt,ofArgb等方法,都可以比较方便的绑定View和对应的属性。

  3、ValueAnimator,继承自Animator

  是ObjectAnimator的父类。它不能绑定到具体的属性上,而且没有重写setTarget方法,而Animator中的setTarget方法为空。所以ValueAnimator实际上没有设置View和对应的属性。这就要求使用者自己获取变化的值,并将值赋给具体View对象的属性。

  当然,ValueAnimator其实也十分方便,只需要加上监控事件,在监控的事件中处理相关赋值就可以了。

     ValueAnimator animator = ValueAnimator.ofFloat(0, mScreenHeight
- mBlueBall.getHeight());
animator.setDuration(1000).start();
animator.addUpdateListener(new AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
mBlueBall.setTranslationY((Float) animation.getAnimatedValue());
}
});

  可以为ValueAnimator设置重复的次数(setRepeatCount)和重复的模式(setRepeatMode),重复的模式可以是(RESTART)或者(REVERSE)。

  4、AnimatorSet,继承自Animator

  如果想要在View上实现多个动画效果,可以借助于AnimatorSet。如果多个动画同时执行,可以使用AnimatorSet.playTogether方法;如果多个动画按顺序执行,可以使用AnimatorSet.playSequentially方法;如果多个动画没有统一的执行顺序,AnimatorSet提供了play,with,before,after来设置多个动画执行的顺序。

  

  5、PropertyValuesHolder

  PropertyValuesHolder是属性(Property)和值(Value)的对应。ValueAnimator和ObjectAnimator对应的ofInt、ofFloat等都是借助于PropertyValuesHolder来实现的。

  对于在View上实现多个动画效果的要求,也可以使用PropertyValuesHolder来实现。ValueAnimator和ObjectAnimator都提供了方法,可以传入多个PropertyValuesHolder对象,来实现在多个属性上同时产生动画效果的要求。  

     PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f, 0f, 1f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 1f, 0, 1f);
PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("rotationX", 0f, 180, 360f);
ObjectAnimator.ofPropertyValuesHolder(iv_src, pvhX, pvhY, pvhZ).setDuration(2000).start();

  6、xml

  也可以使用xml文件来定义属性函数,然后在程序中使用AnimatorInflater.loadAnimator方法加载属性动画。xml中,可以使用<set>、<objectAnimator>。

三、监听类

  1、AnimatorUpdateListener

  在ValueAnimator的时候提到了这个监听类。它在计算的值发生改变的时候回调,只包含一个方法。是ValueAnimator中定义的内部类。

    /**
* Implementors of this interface can add themselves as update listeners
* to an <code>ValueAnimator</code> instance to receive callbacks on every animation
* frame, after the current frame's values have been calculated for that
* <code>ValueAnimator</code>.
*/
public static interface AnimatorUpdateListener {
/**
* <p>Notifies the occurrence of another frame of the animation.</p>
*
* @param animation The animation which was repeated.
*/
void onAnimationUpdate(ValueAnimator animation); }

  2、AnimatorListener

  在属性动画的开始、结束、取消、重复的时候回调,在Animator中定义的内部类。

    /**
* <p>An animation listener receives notifications from an animation.
* Notifications indicate animation related events, such as the end or the
* repetition of the animation.</p>
*/
public static interface AnimatorListener {
/**
* <p>Notifies the start of the animation.</p>
*
* @param animation The started animation.
*/
void onAnimationStart(Animator animation); /**
* <p>Notifies the end of the animation. This callback is not invoked
* for animations with repeat count set to INFINITE.</p>
*
* @param animation The animation which reached its end.
*/
void onAnimationEnd(Animator animation); /**
* <p>Notifies the cancellation of the animation. This callback is not invoked
* for animations with repeat count set to INFINITE.</p>
*
* @param animation The animation which was canceled.
*/
void onAnimationCancel(Animator animation); /**
* <p>Notifies the repetition of the animation.</p>
*
* @param animation The animation which was repeated.
*/
void onAnimationRepeat(Animator animation);
}

  3、AnimatorPauseListener

  在属性动画暂停、继续执行的时候回调,在Animator类中定义的内部类。

    /**
* A pause listener receives notifications from an animation when the
* animation is {@link #pause() paused} or {@link #resume() resumed}.
*
* @see #addPauseListener(AnimatorPauseListener)
*/
public static interface AnimatorPauseListener {
/**
* <p>Notifies that the animation was paused.</p>
*
* @param animation The animaton being paused.
* @see #pause()
*/
void onAnimationPause(Animator animation); /**
* <p>Notifies that the animation was resumed, after being
* previously paused.</p>
*
* @param animation The animation being resumed.
* @see #resume()
*/
void onAnimationResume(Animator animation);
}

  AnimatorListener和AnimatorPauseListener有一个共同的实现类——AnimatorListenerAdapter 。这个类实现了两个接口的所有方法,但是它是一个抽象类,它实现的方法都是空方法,所以没有任何意义。只是如果我们想继承AnimatorListener或者AnimatorPauseListener,但是不想实现所有方法时,使用AnimatorListenerAdapter会很方便。

四、属性动画的其他功能

1、Interpolator

  Interpolator表示变化率。它可以把输入的匀速的变化转换成加速、减速等不同的变化率。Android提供了以下Interpolator的实现类:    

  • AccelerateDecelerateInterpolator 在动画开始与结束的地方速率改变比较慢,在中间的时候加速
  • AccelerateInterpolator  在动画开始的地方速率改变比较慢,然后开始加速
  • AnticipateInterpolator 开始的时候向后然后向前甩
  • AnticipateOvershootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值
  • BounceInterpolator   动画结束的时候弹起
  • CycleInterpolator 动画循环播放特定的次数,速率改变沿着正弦曲线
  • DecelerateInterpolator 在动画开始的地方快然后慢
  • LinearInterpolator   以常量速率改变
  • OvershootInterpolator    向前甩一定值后再回到原来位置

  如果上面的实现类仍然不能满足具体的场景,可以自己实现Interpolator,只需要实现float getInterpolation(float input)方法就可以了。

  Animator提供setInterpolator(TimeInterpolator)方法用于设置变化率。而实际上Interpolator接口就直接继承了TimeInterpolator接口,并且没有新增加任何方法或常量等信息。所以Interpolator和TimeInterpolator完全等价。

  Animation(补间动画)及其子类,包含方法setInterpolator(Interpolator),所以Android提供的这些变化率实现类同样适用于补间动画。

  2、TypeEvaluator

  类型估值,用于计算并返回属性值。

  TypeEvaluator的定义如下:

public interface TypeEvaluator<T> {

    public T evaluate(float fraction, T startValue, T endValue);

}

  3、我个人的理解是这样,首先通过Interpolator将匀速的变化变成自己想要的变化率,然后再使用TypeEvaluator将这个变化率转换成自己想要的数据(可能是位置对应的Point,或者其他结构的数据(比如,把位置信息和alpha值一起组装成一个类,表示透明度和位置有明确的相关性),甚至可以是按照某种规则实现的boolean也未尝不可,如此等等的逻辑可以在这里实现)。

  那现在有一个问题,既然Interpolator和TypeEvaluator都是计算值,为什么不把二者合在一起?个人认为可以这样理解,这包含了一种解耦的思想。Interpolator表示速率的变化,是匀速的,是越来越快的,还是先快后慢的等等;而TypeEvaluator则用于计算View的实际状态。两者分开之后,不但在开始设计的时候降低了复杂度,而且可以达到更好的扩展性。如果想要调整变化率,修改Interpolator,如果想要修改View的显示规则,则修改TypeEvaluator。  

        ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setDuration(3000);
valueAnimator.setObjectValues(new PointF(0, 0));
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.setEvaluator(new TypeEvaluator<PointF>()
{
// fraction = t / duration
@Override
public PointF evaluate(float fraction, PointF startValue,
PointF endValue)
{
Log.e(TAG, fraction * 3 + "");
// x方向200px/s ,则y方向0.5 * 10 * t
PointF point = new PointF();
point.x = 200 * fraction * 3;
point.y = 0.5f * 200 * (fraction * 3) * (fraction * 3);
return point;
}
}); valueAnimator.start();
valueAnimator.addUpdateListener(new AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
PointF point = (PointF) animation.getAnimatedValue();
mBlueBall.setX(point.x);
mBlueBall.setY(point.y); }
});

参考: Android 属性动画(Property Animation) 完全解析 (上)

属性动画总结(Property Animation)的更多相关文章

  1. Android(java)学习笔记263:Android下的属性动画(Property Animation)

    1. 属性动画(Property Animation)引入: 在手机上去实现一些动画效果算是件比较炫酷的事情,因此Android系统在一开始的时候就给我们提供了两种实现动画效果的方式,逐帧动画(fra ...

  2. Android 属性动画(Property Animation) 全然解析 (下)

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38092093 上一篇Android 属性动画(Property Animatio ...

  3. Android 属性动画(Property Animation) 完全解析 (下)

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38092093 上一篇Android 属性动画(Property Animatio ...

  4. 通过AnimationSet 同步或一部播放多个动画 Android 属性动画(Property Animation) 完全解析 (下)

    AnimationSet提供了一个把多个动画组合成一个组合的机制,并可设置组中动画的时序关系,如同时播放,顺序播放等. 以下例子同时应用5个动画: 播放anim1: 同时播放anim2,anim3,a ...

  5. Android(java)学习笔记207:Android下的属性动画(Property Animation)

    1. 属性动画(Property Animation)引入: 在手机上去实现一些动画效果算是件比较炫酷的事情,因此Android系统在一开始的时候就给我们提供了两种实现动画效果的方式,逐帧动画(fra ...

  6. Android 属性动画(Property Animation) 完全解析 (上)

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38067475 1.概述 Android提 供了几种动画类型:View Anima ...

  7. 【转】Android 属性动画(Property Animation) 完全解析 (上)

    http://blog.csdn.net/lmj623565791/article/details/38067475 1.概述 Android提供了几种动画类型:View Animation .Dra ...

  8. Android 属性动画(Property Animation) 全然解析 (上)

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38067475 1.概述 Android提供了几种动画类型:View Animat ...

  9. 属性动画(Property Animation)资源

    Animator 代表一个属性动画,但它只是一个抽象类,通常会使用它的子类:AnimatorSet.ValueAnimator.ObjectAnimator.TimeAnimator. 定义属性动画的 ...

  10. Android动画基础——属性动画(Property Animation)

    本篇涉及例子下载:Github 本篇讲android 3.0引入的属性动画框架,上篇写视图动画View Animation时就说过ViewAnimation的缺点,那就是动画作用的是view本身的视觉 ...

随机推荐

  1. Redis漏洞,远程攻击

    文章转自http://blog.csdn.net/whs_321/article/details/51734602 http://blog.knownsec.com/2015/11/analysis- ...

  2. 在Eclipse中运行Web项目Jsp网页时提示端口被占用的解决办法:Several ports (8005, 8888, 8009) required by Tomcat v9.0 Server at localhost are already in use.

    问题: 在Eclipse中运行Web项目Jsp网页启动Tomcat时提示端口被占用: Several ports (8005, 8080, 8009) required by Tomcat v9.0 ...

  3. 开源项目Bug悬赏任务

    导读 2014 年开源加密库 OpenSSL 项目爆出的高危漏洞 Heartblood 让世人意识到一些鲜为人知的开源项目对整个互联网和其它基础设施的完整性和可靠性至关重要,随后 Linux 基金会发 ...

  4. ansible详解

    Ansible默认通过 SSH 协议管理机器. 安装Ansible之后不需要启动或运行一个后台进程,或是添加一个数据库.只要在一台电脑(可以是一台笔记本)上安装好,就可以通过这台电脑管理一组远程的机器 ...

  5. Apache IOUtils的使用

    IOUtils 与 FileUtilsCommons IO 是 apache 的一个开源的工具包,封装了 IO操作的相关类,使用 Commons IO 可以很方便的读写文件 commons.jar 包 ...

  6. 数据库连接不关闭造成的问题以及RowSet的使用

    这几天给项目做性能压力测试,发现一个方法压力200之后就会把整个系统弄停掉.仔细检查发现是开发人员调用数据库的写法有问题.用的是spring的jdbcTemplate,在使用回调的时候,在回调里又做了 ...

  7. Vue-接口跨域请求调试proxyTable

    在项目开发的时候,接口联调的时候一般都是同域名下,且不存在跨域的情况下进行接口联调,但是当我们现在使用vue-cli进行项目打包的时候,我们在本地启动服务器后,比如本地开发服务下是 http://lo ...

  8. [Spark][Python]对HDFS 上的文件,采用绝对路径,来读取获得 RDD

    对HDFS 上的文件,采用绝对路径,来读取获得 RDD: In [102]: mydata=sc.textFile("file:/home/training/test.txt")1 ...

  9. PCB之PASTE助焊层和SOLDER阻焊层

    1.PASTE为焊接层,用于SMT贴片元件的焊接,对应的图形为钢网(钢网上的小孔): 2.SOLDER为阻焊层,它代表的是绿油的涂抹区域,且为负片输出(负片输出指的是图形以外的区域为有效区域): PA ...

  10. P4099 [HEOI2013]SAO

    P4099 [HEOI2013]SAO 贼板子有意思的一个题---我()竟然没看题解 有一张连成树的有向图,球拓扑序数量. 树形dp,设\(f[i][j]\)表示\(i\)在子树中\(i\)拓扑序上排 ...