android平台下,动画实现Metro动态磁贴特效

博客介绍了如何在Android平台上,通过自定义动画而非继承ImageView,实现Metro动态磁贴特效。作者强调现有方法的局限性,并分享了自己的实现方式,包括重写Animation的相关方法。文章附带主界面类和布局文件代码,展示运行效果。
摘要由CSDN通过智能技术生成

网上有很多Win8动态磁贴特效的代码,但是都是使用基于继承ImageView的自定义类,这种实现方法有一个短板就是该类要实现Metro特效必须是以图片为背景的,而且scaleType必须只能指定为matrix。不然特效就出不来。

自己参考了网上的代码很久,自己琢磨出来了使用动画来实现Metro特效,通过继承自Animation来重写里面的protected void applyTransformation(float interpolatedTime, Transformation t)、public boolean getTransformation(long currentTime, Transformation outTransformation)和public void initialize(int width, int height, int parentWidth, int parentHeight) 方法实现的,废话不多说,上代码:

自定义动画类:

<pre name="code" class="java">package com.hwlong.Utils;

import android.graphics.Camera;
import android.graphics.Matrix;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.Transformation;

/**
 * 动态磁贴动画
 * 
 * @author HeJie
 * 
 */
public class MetroAnimation extends Animation {

	private int touchX;  //触控X坐标
	private int touchY;  //触控Y坐标
	private int mHeight; //View的高度
	private int mWidth;  //View的宽度
	private int count;
	private View view; //动画对应的View
	private boolean XbigY = false;
	private boolean isScale = false;  //true使用放缩特效,false则使用反转特效

	private boolean mPaused = false;
	private boolean isPause = true;
	private long mElapsedAtPause = 0;

	private float RotateX = 0;
	private float RotateY = 0;
	private float minK = 0.012f;  //放缩函数的斜率

	private Camera camera;

	public MetroAnimation() {
		super();
		camera = new Camera();
	}

	/**
	 * 设置点击的位置、viewID等信息
	 * @param touchX
	 * @param touchY
	 * @param ViewID
	 */
	public void setTouchPoint(int touchX, int touchY, View view) {
		this.touchX = touchX;
		this.touchY = touchY;
		this.view = view;
	}
	
	@Override
	protected void applyTransformation(float interpolatedTime, Transformation t) {
		super.applyTransformation(interpolatedTime, t);

		if (isScale) {
			if (!mPaused) {
				float s = 0;
				if (count < 10) {
					//根据count的值 计算放缩率s的值
					s = (1f - count * minK);
					BeginScale(t.getMatrix(), s);
				} else if (count < 20) {
					//放缩特效执行一半时,自动暂停
					if (count == 10 && isPause) {
						Pause();
					}
					s = 1f + (count - 19) * minK;
					BeginScale(t.getMatrix(), s);
				} else {
					view.clearAnimation();
				}
				count++;
			} else {
				//暂停时缩小矩阵至最小状态
				BeginScale(t.getMatrix(), (1f - 10 * minK));
			}
		} else {
			if (!mPaused) {
				if (count < 10) {
					//count为旋转的角度
					BeginRotate(t.getMatrix(), (XbigY ? count : 0), (XbigY ? 0
							: count));
				} else if (count <= 20) {
					//旋转特效执行一半时,自动暂停
					if (count == 10 && isPause) {
						Pause();
					}
					//(20 - count)为旋转的角度值
					BeginRotate(t.getMatrix(), (XbigY ? 20 - count : 0),
							(XbigY ? 0 : 20 - count));
				} else {
					view.clearAnimation();
				}
				count += 2;
			} else {
				//暂停时旋转矩阵至最大状态
				BeginRotate(t.getMatrix(), (XbigY ? 10 : 0), (XbigY ? 0 : 10));
			}
		}

	}

	@Override
	public boolean getTransformation(long currentTime,
			Transformation outTransformation) {
		//设置暂停后第一次调用该方法,记录暂停时用过的时间
		if (mPaused && mElapsedAtPause == 0) {
			mElapsedAtPause = currentTime - getStartTime();
		}
		if (mPaused)
			//设置开始时间,不然动画会随暂停的时间流逝而停止
			setStartTime(currentTime - mElapsedAtPause);
		return super.getTransformation(currentTime, outTransformation);
	}

	/**
	 * 暂停动画
	 */
	public void Pause() {
		mElapsedAtPause = 0;
		mPaused = true;
	}

	/**
	 * 恢复动画
	 */
	public void Resume() {
		mPaused = false;
		isPause = false;
	}

	@Override
	public void initialize(int width, int height, int parentWidth,
			int parentHeight) {
		super.initialize(width, height, parentWidth, parentHeight);
		mWidth = width;
		mHeight = height;
		count = 0;
		isPause = true;
		Rot
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值