功能非常簡單,但實現起來卻沒想像中的那麼簡單,如果不用android的動畫,而是自己用線程開始動畫,這種方式可以實現,但不推薦
我這裏採用的是ObjectAnimator動畫,至於這個動畫的使用教程,請自行查閱相關資料
ObjectAnimator動畫中,有三個方法:
objAnim.start(); 動畫開始,從你設置的起始點開始
objAnim.cancel(); 動畫取消,動畫停在當前位置
objAnim.end(); 動畫結束,動畫停止在起始位置
一切看起來非常簡單,但實現效果是:每次調用 objAnim.start() 時,動畫都是從頭開始,我要的效果是從上次運行的位置開始,
先說下實現原理:
ObjectAnimator可以監聽當前動畫執行的位置,我們可以把當前位置記錄下來,當動畫停止時,該值便會被保存,那麼下次運行時,便以這個值爲起點,這裏以一個仿360雷達掃描爲例:
我把該動畫獨立出來,做成一個控件,相關注釋都有,項目下載地址:http://download.csdn.net/detail/ytmfdw/8605503
注意:項目中,沒完成這個要求,請按以下代碼修改。
package com.ytmfdw.radar;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.FrameLayout;
import android.widget.ImageView;
@SuppressLint("NewApi")
public class Radar extends FrameLayout {
public static final String TAG = "Radar";
private ImageView im_scan;
private ImageView im_dian;
private AlphaAnimation animation2;
private float currentValue = 0f;
private ObjectAnimator objAnim = null;
public Radar(Context context) {
super(context);
// TODO Auto-generated constructor stub
initView(context);
}
public Radar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
// TODO Auto-generated constructor stub
}
public Radar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView(context);
}
@SuppressLint("NewApi")
public void initView(Context context) {
LayoutInflater.from(context).inflate(R.layout.radar, this);
im_scan = (ImageView) findViewById(R.id.im_scan);
im_dian = (ImageView) findViewById(R.id.im_dian);
animation2 = new AlphaAnimation(0.0f, 1.0f);
animation2.setDuration(3000);
animation2.setRepeatCount(Animation.INFINITE);
startAnimation();
}
@Override
protected void onAttachedToWindow() {
// TODO Auto-generated method stub
super.onAttachedToWindow();
// 當控件被加載到窗體中時,開始執行動畫
objAnim.start();
im_dian.startAnimation(animation2);
}
/**
* 開始動畫
* */
@SuppressLint("NewApi")
public void startAnimation() {
// 設置動畫,從上次停止位置開始,這裏是順時針旋轉360度
objAnim = ObjectAnimator.ofFloat(im_scan, "Rotation",
currentValue - 360, currentValue);
// 設置持續時間
objAnim.setDuration(1000);
// 設置循環播放
objAnim.setRepeatCount(ObjectAnimator.INFINITE);
// 設置動畫監聽
objAnim.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// TODO Auto-generated method stub
// 監聽動畫執行的位置,以便下次開始時,從當前位置開始
currentValue = (Float) animation.getAnimatedValue();
}
});
objAnim.start();
im_dian.startAnimation(animation2);
}
/**
* 停止動畫
* */
public void stopAnimation() {
objAnim.end();
im_dian.clearAnimation();
currentValue = 0;// 重置起始位置
}
/**
* 暫停動畫
* */
@SuppressLint("NewApi")
public void pauseAnimation() {
objAnim.cancel();
im_dian.clearAnimation();// 清除此ImageView身上的動畫
}
@Override
protected void onDetachedFromWindow() {
// TODO Auto-generated method stub
super.onDetachedFromWindow();
// 控件被移除時,取消動畫
objAnim.cancel();
im_scan.clearAnimation();// 清除此ImageView身上的動畫
im_dian.clearAnimation();// 清除此ImageView身上的動畫
}
public boolean isRunning() {
return objAnim.isRunning();// 判斷動畫是否在跑
}
}