<Android 基础(三十一)> ObjectAnimator
简介
ObjectAnimator,是ValueAnimator的子类,支持利用目标视图的属性来实现动画效果。构造ObjectAnimator的时候,将会提取对应的参数来定义动画对象和对象属性。合适的get/set方法是视图实现属性动画的内部机理,动画过程中,系统将通过get/set方法来实现效果,也就是根据一定的规律来为View设置属性。
Animators可以用过资源文件或者是代码定义,当使用资源文件创建的时候,若使用PropertyValuesHolder和Keyframe可以创建出更加复杂的动画,使用PropertyValuesHolder可以实现几个属性的并行变化。
使用Keyframes,可以实现更复杂的动画过程中的属性变化方式。我们可以为每一个Keyframes明确一个fractional value(因子,0-1)来决定在整个动画过程中什么时候到达这个属性值。不设置fractions的时候,这些关键帧将会均匀的分布在整个动画过程中。至于那些没有指定value值的关键帧,将会在动画开始的时候推导出他们的 value。初次之外,我们可以给关键帧添加插值器,整个插值器将会在被设置的这一帧和前一帧动画之间。对于没有设置插值器的关键帧,将会给他们提供一个默认的插值器AccelerateDecelerateInterpolator
XML实现
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:repeatCount="1"
    android:repeatMode="reverse">
    <!-- BEGIN_INCLUDE(KeyframeResources) -->
    <propertyValuesHolder android:propertyName="x">
        <keyframe
            android:fraction="0"
            android:value="800" />
        <keyframe
            android:fraction=".2"
            android:interpolator="@android:anim/accelerate_interpolator"
            android:value="1000" />
        <keyframe
            android:fraction="1"
            android:interpolator="@android:anim/accelerate_interpolator"
            android:value="400" />
    </propertyValuesHolder>
    <propertyValuesHolder android:propertyName="y">
        <keyframe />
        <keyframe
            android:fraction=".2"
            android:interpolator="@android:anim/accelerate_interpolator"
            android:value="300" />
        <keyframe
            android:interpolator="@android:anim/accelerate_interpolator"
            android:value="1000" />
    </propertyValuesHolder>
    <!-- END_INCLUDE(KeyframeResources) -->
</objectAnimator>
| objectAnimator属性值 | 含义 | 
|---|---|
| android:propertyName | 属性名称 | 
| android:valueTo | 动画结束时属性的值 | 
| android:valueFrom | 动画开始时属性的值 | 
| android:duration | 动画时长 | 
| android:startOffset | 动画延迟几秒播放,调用start()方法后延迟 | 
| android:repeatCount | 动画重复次数 | 
| android:repeatMode | 动画重复的方式,restart/reverse | 
| android:valueType | 属性值类型,intType,floatType,colorType,pathType | 
propertyValuesHolder属性值和objectAnimator基本相同
| keyframe属性值 | 含义 | 
|---|---|
| android:fraction | 插值因子 | 
| android:interpolator | 插值器,用在当前帧和前一帧之间 | 
| android:value | 需要设置的属性值 | 
代码实现
public class MainActivity extends AppCompatActivity {
    private int width;
    private int height;
    private ImageView imageView = null;
    private ImageView loveImageView = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        toolbar.setNavigationIcon(R.drawable.left);
        setSupportActionBar(toolbar);//设置ActionBar
        getWidthAndHeight();//获取屏幕大小
        imageView = (ImageView) findViewById(R.id.ball);
        loveImageView = (ImageView) findViewById(R.id.love);
    }
    /*
      心跳
     */
    public void doAnimation(final View view) {
        PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f,
                0.8f, 1f, 0.8f, 1.0f);
        PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 0.6f,
                0.8f, 1f, 0.8f, 1.0f);
        PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("scaleY", 0.6f,
                0.8f, 1f, 0.8f, 1.0f);
        ObjectAnimator.ofPropertyValuesHolder(loveImageView, pvhX, pvhY, pvhZ).setDuration(1000).start();//创建属性动画并开始
    }
    /*
    抛物线
     */
    public void doGtAnimation(final View view) {
        ObjectAnimator anim = ObjectAnimator.ofFloat(imageView, "yidong", 0, 1, 0).setDuration(3000);
        /*设置动画更新监听器,通过手动设置属性来实现view属性的改变达到动画的效果*/
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float cVal = (Float) animation.getAnimatedValue();
                imageView.setX(5 * cVal * 100);
                imageView.setY(5 * cVal * 3 * cVal * 3 * 100);
            }
        });
        /*设置动画过程监听器,监听开始结束取消等动作*/
        anim.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                System.err.println("yidong -- onAnimationStart");
            }
            @Override
            public void onAnimationEnd(Animator animation) {
                System.err.println("yidong -- onAnimationEnd");
            }
            @Override
            public void onAnimationCancel(Animator animation) {
                System.err.println("yidong -- onAnimationCancel");
            }
            @Override
            public void onAnimationRepeat(Animator animation) {
                System.err.println("yidong -- onAnimationRepeat");
            }
        });
        /*重复魔石*/
        anim.setRepeatMode(ValueAnimator.RESTART);
        /*重复次数*/
        anim.setRepeatCount(2);
        anim.start();
    }
    /*
    转圈圈
     */
    public void doCircleAnimation(View view) {
        ObjectAnimator anim = ObjectAnimator.ofFloat(imageView, "yidong", 0, 2 * (float) Math.PI).setDuration(1000);
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                System.err.println("yidong -- value = " + animation.getAnimatedValue());
                float cVal = (Float) animation.getAnimatedValue();
                imageView.setX((float) Math.sin(cVal) * 200 + width / 2);
                imageView.setY((float) Math.cos(cVal) * 200 + height / 2);
            }
        });
        anim.setRepeatMode(ValueAnimator.REVERSE);
        anim.setRepeatCount(-1);//无限重复
        anim.start();
    }
    /*
    从xml文件中提取动画
     */
    public void doXmlAnimation(View view) {
        Animator animator = AnimatorInflater.loadAnimator(this, R.animator.one);//从xml文件中添加动画
        animator.setTarget(loveImageView);
        animator.start();
    }
    /*
    获取屏幕的宽高
     */
    private void getWidthAndHeight() {
        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        DisplayMetrics dm = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(dm);
        width = dm.widthPixels;
        height = dm.heightPixels;
        System.err.println("yidong -- width = " + width);
        System.err.println("yidong -- height = " + height);
    }
}
实际效果
写在最后
属性动画的内容很丰富,这里只是提到了ObjectAnimator的一些简单实现,很深入和全面的东西,需要自己看源码,熟悉对应的API
<Android 基础(三十一)> ObjectAnimator的更多相关文章
- Bootstrap <基础三十一>插件概览
		
在前面布局组件中所讨论到的组件仅仅是个开始.Bootstrap 自带 12 种 jQuery 插件,扩展了功能,可以给站点添加更多的互动.即使不是一名高级的 JavaScript 开发人员,也可以着手 ...
 - <Android基础>(三) UI开发 Part 3 RecyclerView
		
RecyclerView 1)RecyclerView的基本用法 2)横向滚动和瀑布流滚动 3)注册点击事件 3.6 强大的滚动控件 RecyclerView ListView缺点: 1.不使用技巧优 ...
 - <Android基础>(三) UI开发 Part 2 ListView
		
ListView 1)ListView的简单用法 2)定制ListView界面 3)提升ListView的运行效率 4)ListView的点击事件 3.5 ListView 3.5.1 ListVie ...
 - <Android 基础(十一)> Snackbar
		
介绍 Snackbars provide lightweight feedback about an operation. They show a brief message at the botto ...
 - <Android基础>(三) UI开发 Part 1
		
1.常用控件 1)TextView 2)Button 3)EditText 4)ImageView 5)ProgressBar 6)AlertDialog 7)ProgressDialog 2.四种布 ...
 - Bootstrap <基础三十二>模态框(Modal)插件
		
模态框(Modal)是覆盖在父窗体上的子窗体.通常,目的是显示来自一个单独的源的内容,可以在不离开父窗体的情况下有一些互动.子窗体可提供信息.交互等. 如果您想要单独引用该插件的功能,那么您需要引用 ...
 - Bootstrap <基础三十>Well
		
Well 是一种会引起内容凹陷显示或插图效果的容器 <div>.为了创建 Well,只需要简单地把内容放在带有 class .well 的 <div> 中即可.下面的实例演示了 ...
 - Bootstrap <基础二十一>徽章(Badges)
		
Bootstrap 徽章(Badges).徽章与标签相似,主要的区别在于徽章的边角更加圆滑. 徽章(Badges)主要用于突出显示新的或未读的项.如需使用徽章,只需要把 <span class= ...
 - Bootstrap<基础三> 排版
		
Bootstrap 使用 Helvetica Neue. Helvetica. Arial 和 sans-serif 作为其默认的字体栈. 使用 Bootstrap 的排版特性,您可以创建标题.段落. ...
 - Android基础夯实--重温动画(五)之属性动画 ObjectAnimator详解
		
只有一种真正的英雄主义 一.摘要 ObjectAnimator是ValueAnimator的子类,它和ValueAnimator一样,同样具有计算属性值的功能,但对比ValueAnimator,它会更 ...
 
随机推荐
- log4j UdpAppender
			
package cappender;import org.apache.log4j.AppenderSkeleton;import org.apache.log4j.Layout;import org ...
 - 解决 ORA-27102: out of memory
			
记一次故障处理总结: 操作系统:windows server 2008 R2数据库版本:11.2.0.2 故障描述:外部应用连接数据库,提示连接不正常: 排错过程:1.首先 检查数据库监听服务状态是否 ...
 - Windows下调试hadoop
			
1. 本地模式 本地模式下调试hadoop:下载winutils.exe和hadoop.dll hadoop.lib等windows的hadoop依赖文件放在D:\proc\hadoop\bin目 ...
 - (转载)elasticsearch 查询(match和term)
			
原文地址:https://www.cnblogs.com/yjf512/p/4897294.html elasticsearch 查询(match和term) es中的查询请求有两种方式,一种是简易版 ...
 - mycat中间件--linux安装mycat1.6版本
			
一.mycat安装前准备1.mycat下载地址,点击此处进行下载2.环境要求如下: mycat使用Java开发,因为用到了JDK 7的部分功能,所以在使用前请确保安装了JDK 7.0,并设置了正确的J ...
 - ActiveMQ——activemq的使用java代码实例(精选)
			
ActiveMQ 在java中的使用,通过单例模式.工厂实现 Jms规范里的两种message传输方式Topic和Queue,两者的对比如下表(): Topic Queue 概要 Publish ...
 - Linux进程间的通信
			
一.管道 管道是Linux支持的最初Unix IPC形式之一,具有以下特点: A. 管道是半双工的,数据只能向一个方向流动: B. 需要双工通信时,需要建立起两个管道: C. 只能用于父子进程或者兄弟 ...
 - C++类型转化小结
			
之前面试就有被问过关于使用类型转换的问题,因为主要是做Windows驱动的开发,一直都是纯C语言+汇编,当时真的是只用过C语言的强制类型转换,C语言的强制类型转换(Type Cast)很简单,不管什么 ...
 - <Think Python>中统计文献单词的处理代码
			
def process_line(line, hist): """Adds the words in the line to the histogram. Modi ...
 - Java设计模式学习记录-建造者模式
			
前言 今天周末,有小雨,正好也不用出门了,那就在家学习吧,经过了两周的面试,拿到了几个offer,但是都不是自己很想去的那种,要么就是几个人的初创小公司,要么就是开发企业内部系统的这种传统开发,感觉这 ...