项目需求,需要做一个加载动画,如效果图:(demo下载地址https://github.com/gerenvip/TestNineOldAndroid)
主要使用的是属性动画,demo(上面贴出的github地址可以下载)中使用的nineoldAndroid 开源的项目,如果不清楚该项目的可以到github上搜索,或者看一下任玉刚大神的博客 http://blog.csdn.net/singwhatiwanna/article/details/17639987
实现代码:
package com.gerenvip.test.nine;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.widget.ImageView;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.AnimatorListenerAdapter;
import com.nineoldandroids.animation.AnimatorSet;
import com.nineoldandroids.animation.ObjectAnimator;
import com.nineoldandroids.view.ViewHelper;
public class MyActivity extends Activity {
private ImageView targView1;
private ImageView targView2;
private ImageView targView3;
private int mScreenWith;
private int mScreenHeight;
private AnimatorSet set1;
private AnimatorSet set2;
private AnimatorSet set3;
private boolean flag = false;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
//获取屏幕的高度
mScreenHeight = dm.heightPixels;
//获取屏幕的宽度
mScreenWith = dm.widthPixels;
targView1 = (ImageView) findViewById(R.id.iv_i);
targView2 = (ImageView) findViewById(R.id.iv_u1);
targView3 = (ImageView) findViewById(R.id.iv_u2);
//有3个图片,我使用三个AnimatorSet
set1 = createAnima(targView1);
set2 = createAnima(targView2);
set3 = createAnima(targView3);
//监听第一个animatorset执行情况
set1.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
//第一个动画执行的时候,是不需要显示后两个动画的,所以,将targView2 targView3隐藏
targView2.setVisibility(View.INVISIBLE);
targView3.setVisibility(View.INVISIBLE);
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
//flag标记动画是否停止
if (flag) {
//当第一个动画执行完毕,立刻指定第二个动画
set2.start();
}
}
});
set2.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (flag) {
//第二个动画执行完毕,执行第三个
set3.start();
}
}
@Override
public void onAnimationStart(Animator animation) {
//当第二个动画开始的时候为了看到效果,将刚才隐藏的targView2显示出来,这里使用postDelayed的原因是,如果直接setVisibility,会不生效
targView2.postDelayed(new Runnable() {
@Override
public void run() {
targView2.setVisibility(View.VISIBLE);
}
}, 100);
}
});
set3.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
//当三个动画都执行完一遍后,重新开启动画1,如此实现无限循环
if (flag) {
set1.start();
}
}
@Override
public void onAnimationStart(Animator animation) {
//第三个动画执行的时候,将targView3 显示可见
targView3.postDelayed(new Runnable() {
@Override
public void run() {
targView3.setVisibility(View.VISIBLE);
}
}, 100);
}
});
}
/**
* 创建三个动画集合
*动画分解为7个步骤:
* 1.竖直的图片旋转-30度
* 2.图片下落一个较高的高度
* 3.弹起
* 4.在弹起的过程中,将图片旋转到0度,即恢复以前的位置
* 5.当弹起到顶部的时候,再次下落
* 6.在下落的过程中,图片旋转到+30度
* 7.当图片落到底部的时候,在旋转到0度,恢复竖直位置
* @param targView
* @return
*/
private AnimatorSet createAnima(final ImageView targView) {
final AnimatorSet set = new AnimatorSet();
//第一次下落比较高的距离
float longHeight = mScreenHeight * (float) 0.3;
//弹起的一个比较短的一个距离
float shortHeight = longHeight - mScreenHeight * (float) 0.1;
//下落时间
long downAnimTime = 300;
long otherTime = 100;
//顺时针旋转的角度
float positiveDegree = 30;
//逆时针旋转角度
float negativeDegree = -30;
//初始化动画,时间很短,不需要用户看到,将本来竖直的图片逆时针旋转30度:0 -->-30
ObjectAnimator initAnim = ObjectAnimator.ofFloat(targView, "rotation", 0, negativeDegree);
initAnim.setDuration(1);
initAnim.setInterpolator(new AccelerateInterpolator());
//图片第一个下落动画
ObjectAnimator traYdown = ObjectAnimator.ofFloat(targView, "translationY", 0, longHeight);
traYdown.setDuration(downAnimTime);
traYdown.setInterpolator(new AccelerateInterpolator());
//弹起动画
ObjectAnimator traYUp = ObjectAnimator.ofFloat(targView, "translationY", longHeight, shortHeight);
traYUp.setInterpolator(new AccelerateInterpolator());
traYUp.setDuration(otherTime);
//弹起的过程中,应该执行的旋转为原始位置的动画,-30 -->0
ObjectAnimator roationz = ObjectAnimator.ofFloat(targView, "rotation", negativeDegree, 0);
roationz.setDuration(otherTime);
roationz.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
//设置旋转中心点为图片底部中心点
ViewHelper.setPivotX(targView, targView.getMeasuredWidth() / 2);
ViewHelper.setPivotX(targView, targView.getMeasuredHeight());
}
});
roationz.setInterpolator(new AccelerateInterpolator());
//--------------------------------
//弹起到最高点的时候,开始向右旋转 0 --> 30
ObjectAnimator roationr = ObjectAnimator.ofFloat(targView, "rotation", 0, positiveDegree);
roationr.setDuration(otherTime);
roationr.setInterpolator(new AccelerateInterpolator());
roationr.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
//设置旋转中心
ViewHelper.setPivotX(targView, targView.getMeasuredWidth() / 2);
ViewHelper.setPivotX(targView, targView.getMeasuredHeight());
}
});
//第二次下落动画,在下落的过程中执行roationr动画,即下落的同时,向右旋转30度
ObjectAnimator traYdown2 = ObjectAnimator.ofFloat(targView, "translationY", shortHeight, longHeight);
traYdown2.setDuration(otherTime);
traYdown2.setInterpolator(new AccelerateInterpolator());
//--------------------------------
//当落下后,执行旋转动画,将图片旋转为竖直位置
final ObjectAnimator roationz1 = ObjectAnimator.ofFloat(targView, "rotation", positiveDegree, 0);
roationz1.setDuration(otherTime);
roationz1.setInterpolator(new AccelerateInterpolator());
roationz1.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
//设置旋转中心
ViewHelper.setPivotX(targView, targView.getMeasuredWidth() / 2);
ViewHelper.setPivotX(targView, targView.getMeasuredHeight());
}
});
//AnimatorSet播放方法有play和playTogether,其中play支持播放单个动画,playTogether支持同时播放多个动画,注意动画之间的时间顺序
set.play(initAnim).before(traYdown);
set.play(traYdown).before(traYUp);
set.playTogether(traYUp, roationz);
set.play(roationz).before(traYdown2);
set.playTogether(traYdown2, roationr);
set.play(roationz1).after(traYdown2);
return set;
}
public void start() {
set1.start();
}
@Override
protected void onDestroy() {
super.onDestroy();
recycleAnim();
}
private void recycleAnim() {
Log.e("WW", "回收资源");
set1.cancel();
set2.cancel();
set3.cancel();
}
public void startSecond(View view) {
Intent intent = new Intent(this, SecondAnimActivity.class);
startActivity(intent);
}
public void startThird(View view) {
Intent intent = new Intent(this, ThridAnimActivity.class);
startActivity(intent);
}
public void startRecord(View view) {
Intent intent = new Intent(this, RecordActivity.class);
startActivity(intent);
}
public void rotate(View view) {
Intent intent = new Intent(this, RotateActivity.class);
startActivity(intent);
}
/**
* 停止/启动动画
* @param view
*/
public void stop(View view) {
if (flag) {
recycleAnim();
flag = false;
} else {
start();
flag = true;
}
}
}