【Android动画九章】-属性动画ObjectAnimator

属性动画是API11之后加入的新特性,属性动画和传统动画有哪些不同,为什么要引入属性动画呢?首先通过一个例子比较一下属性动画和传统动画的不同之处。

xml代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="demo.androidwar.com.animator.MainActivity">

    <ImageView
        android:id="@+id/imageview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="translate"
        android:text="translate" />
</LinearLayout>

MainActivity.java:

package demo.androidwar.com.animator;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView=(ImageView)findViewById(R.id.imageview);
        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this,"点我",Toast.LENGTH_SHORT).show();
            }
        });


    }
    public  void  translate(View view){
        TranslateAnimation translateAnimation=new TranslateAnimation(0,200,0,0);
        translateAnimation.setDuration(2000);
        translateAnimation.setFillAfter(true);
        imageView.startAnimation(translateAnimation);
    }
}

这里给图片设置了单击监听,单击图片时会弹出吐司,点击按钮实现传统动画后(设置setFillAfter方法为true,使得图片移动后停下来),图片向右移动了200dp,这时再次单击图片就会发现不会再弹出吐司了,单击图片原来的地方,发现弹出吐司,通过这个实验可以发现,传统动画仅仅改变View的显示,View本身并没有改变。实例运行时的截图如下:
这里写图片描述
将上面translate方法中的传统动画换成属性动画,即MainActivity.java代码如下:

package demo.androidwar.com.animator;

import android.animation.ObjectAnimator;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = (ImageView) findViewById(R.id.imageview);
        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "点我", Toast.LENGTH_SHORT).show();
            }
        });


    }

    public void translate(View view) {
        ObjectAnimator.ofFloat(imageView, "translationX", 0, 200)//动画类型及参数值
                .setDuration(1000)//动画时长
                .start();//开始动画
    }
}

可以看出translate方法中仅仅只有一行代码,ObjectAnimator类调用了三个方法,第一个方法ofFloat方法需要传入四个参数,第一个参数是动画作用的对象,第二个参数是动画类型,第三个参数是起始坐标,第四个参数为结束坐标。第二个方法设置动画时长,第三个方法启动动画。运行项目实例如下:
这里写图片描述
可以看出属性动画移动的是动画作用的对象本身,当然,除了这个特性之外,属性动画还有很多优点,下面会一一展示。下面我们介绍一下属性动画中常用的类ObjectAnimator。
public final class
ObjectAnimator
extends ValueAnimator
java.lang.Object
↳ android.animation.Animator
↳ android.animation.ValueAnimator
↳ android.animation.ObjectAnimator
由继承结构可以看出ObjectAnimator类是final 的,它不可被继承,继承自ValueAnimator。除了上面的平移动画,属性动画还提供了其他多种动画,通过下面实例学习。
1、旋转方法:

 public void rotate(View view){
        ObjectAnimator.ofFloat(imageView,"rotationX",0,360).setDuration(1000).start();//以X轴为轴旋转一圈
        ObjectAnimator.ofFloat(imageView,"rotationY",0,360).setDuration(1000).start();//以Y轴为轴旋转一圈
    }

方法中传入了4个参数,第一个参数是动画作用的对象,第二个参数是动画类型,一种以X轴为轴旋转,一种以Y轴为轴旋转,第三个参数是旋转开始角度,第四个参数是旋转结束角度。
2、尺寸方法:

public void scale(View view){
        ObjectAnimator.ofFloat(imageView,"scaleX",1,2.0f).setDuration(1000).start();
        ObjectAnimator.ofFloat(imageView,"scaleY",1,2.0f).setDuration(1000).start();
    }

方法同样传入四个参数,第一个是动画作用对象,第二个是动画类型,一种以在X轴方向上改变尺寸,一种在Y轴方向上改变尺寸,第三个是起始尺寸,第四个是结束尺寸。
3、透明度方法:

public void alpha(View view){
        ObjectAnimator.ofFloat(imageView,"alpha",1,0.5f).setDuration(1000).start();
    }

方法传入四个参数,第一个是动画作用对象,第二个是动画类型,这里传入字符串alpha,第三个是起始透明度,第四个是结束透明度,下面看一下完整代码。
布局文件代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="demo.androidwar.com.animator.MainActivity">

    <ImageView
        android:id="@+id/imageview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="translate"
        android:text="translate" />
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="rotate"
        android:text="rotate" />
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="scale"
        android:text="scale" />
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="alpha"
        android:text="alpha" />
</LinearLayout>

MainActivity.java:

package demo.androidwar.com.animator;

import android.animation.ObjectAnimator;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends Activity {
    ImageView imageView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = (ImageView) findViewById(R.id.imageview);
        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "点我", Toast.LENGTH_SHORT).show();
            }
        });
    }
    public void translate(View view) {
        ObjectAnimator.ofFloat(imageView, "translationX", 0, 200)//动画类型及参数值
                .setDuration(1000)//动画时长
                .start();//开始动画
    }
    public void rotate(View view){
        ObjectAnimator.ofFloat(imageView,"rotationX",0,360).setDuration(1000).start();//以X轴为轴旋转一圈
        ObjectAnimator.ofFloat(imageView,"rotationY",0,360).setDuration(1000).start();//以Y轴为轴旋转一圈
    }
    public void scale(View view){
        ObjectAnimator.ofFloat(imageView,"scaleX",1,2.0f).setDuration(1000).start();
        ObjectAnimator.ofFloat(imageView,"scaleY",1,2.0f).setDuration(1000).start();
    }
    public void alpha(View view){
        ObjectAnimator.ofFloat(imageView,"alpha",1,0.5f).setDuration(1000).start();
    }
}

运行项目实例:
这里写图片描述
依次单击按钮,动画会依次运行。我们可以看出,上面是使用代码的方法操作属性动画,那么能不能像传统动画那样通过xml文件定义属性动画呢?当然是可以的,下面通过一个实例看一下如何实现。
在res文件夹下新建一个文件夹名为animator,然后新建一个xml文件,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="5000"
    android:propertyName="backgroundColor"
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:valueFrom="#000000"
    android:valueTo="#ffffff"
    android:valueType="intType" >
</objectAnimator>

用一个objectAnimator标签包裹,属性含义参照下表:
这里写图片描述
java部分代码如下:

 public void fromXML(View view){
        //加载属性动画需要用到AnimatorInflater类
        ObjectAnimator objectAnimator = (ObjectAnimator) AnimatorInflater
                .loadAnimator(MainActivity.this, R.animator.background);
        //用于动画计算的需要,如果开始和结束的值不是基本类型的时候,这个方法是需要的。
        objectAnimator.setEvaluator(new ArgbEvaluator());
        //设置动画的设置目标
        objectAnimator.setTarget(imageView);
        objectAnimator.start();
    }

实际开发中还是建议使用代码来实现属性动画,一方面是代码实现比较简单,另一方面是有一些属性是无法提前确定的,需要在代码中动态设置。
运行项目实例如下:
这里写图片描述
**喜欢的朋友请关注我,另欢迎阅读我的电子书
百度阅读:
http://yuedu.baidu.com/ebook/284b41a1e518964bce847c90?pn=1&click_type=10010002&rf=http%3A%2F%2Fblog.csdn.net%2Fyayun0516%2Farticle%2Fdetails%2F51277821
亚马逊:
http://www.amazon.cn/Android-%E7%99%BE%E6%88%98%E7%BB%8F%E5%85%B8-%E5%8D%B7I-%E5%BC%A0%E4%BA%9A%E8%BF%90/dp/B01ER5R9U2?ie=UTF8&keywords=Android%E7%BB%8F%E5%85%B8&qid=1461806976&ref_=sr_1_6&s=digital-text&sr=1-6**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值