属性动画是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**