Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android 路徑動畫制作

android 路徑動畫制作

編輯:關於Android編程

1、前言

今天項目要用到一個類似微信發送麼麼哒,那種屏幕飄表情的功能,所以分析研究了一下,用到的技術應該是路徑動畫,不知道這樣就正不正確,反正就是畫一個路徑線,然後對象根據這個路徑去運動。所以就叫他路徑動畫了。

路徑動畫要首先要解決的問題就是怎麼畫這個路徑?然後路徑畫出來後怎麼取路徑上的所有點的坐標值?

這裡解決這兩個問題就看一個類PathMeasure 這個類接收一個path對象,然後可以根據pathMeasure.getPosTan()可以得到長度比例的坐標值。這兩個問題就直接搞定了。用path畫一個路徑然後取點,動態移動對象,就變成了路徑動畫了。是不是很簡單。

 

2、看效果

\

 

 

3、核心代碼

 

 

/**
 * 撒花
 * 
 * @author yd
 *
 
 用到的知識點:
 	1、android屬性動畫
 	2、Path路徑繪制
 	3、貝塞爾曲線
 * 
 * 
 *
 *
 *
 *
 *
 *
 */
public class FllowerAnimation extends View implements AnimatorUpdateListener {

	/**
	 * 動畫改變的屬性值
	 */
	private float phase1 = 0f;
	private float phase2 = 0f;
	private float phase3 = 0f;

	/**
	 * 小球集合
	 */
	private List fllowers1 = new ArrayList();
	private List fllowers2 = new ArrayList();
	private List fllowers3 = new ArrayList();

	/**
	 * 動畫播放的時間
	 */
	private int time = 4000;
	/**
	 * 動畫間隔
	 */
	private int delay = 500;

	/**
	 * 資源ID
	 */
//	private int resId = R.drawable.fllower_love;

	public FllowerAnimation(Context context) {
		super(context);
		init(context);
//		this.resId = resId;
	}

	@SuppressWarnings(deprecation)
	private void init(Context context) {
		WindowManager wm = (WindowManager) context
				.getSystemService(Context.WINDOW_SERVICE);
		width = wm.getDefaultDisplay().getWidth();
		height = (int) (wm.getDefaultDisplay().getHeight() * 3 / 2f);

		mPaint = new Paint();
		mPaint.setAntiAlias(true);
		mPaint.setStrokeWidth(2);
		mPaint.setColor(Color.BLUE);
		mPaint.setStyle(Style.STROKE);

		pathMeasure = new PathMeasure();

		builderFollower(fllowerCount, fllowers1);
		builderFollower(fllowerCount , fllowers2);
		builderFollower(fllowerCount , fllowers3);

	}

	/**
	 * 寬度
	 */
	private int width = 0;
	/**
	 * 高度
	 */
	private int height = 0;

	/**
	 * 曲線高度個數分割
	 */
	private int quadCount = 10;
	/**
	 * 曲度
	 */
	private float intensity = 0.2f;

	/**
	 * 第一批個數
	 */
	private int fllowerCount = 4;

	/**
	 * 創建花
	 */
	private void builderFollower(int count, List fllowers) {

		int max = (int) (width * 3 / 4f);
		int min = (int) (width / 4f);
		Random random = new Random();
		for (int i = 0; i < count; i++) {
			int s = random.nextInt(max) % (max - min + 1) + min;
			Path path = new Path();
			CPoint CPoint = new CPoint(s, 0);
			List points = builderPath(CPoint);
			drawFllowerPath(path, points);
			Fllower fllower = new Fllower();
			fllower.setPath(path);
			fllowers.add(fllower);
		}

	}

	/**
	 * 畫曲線
	 * @param path
	 * @param points
	 */
	private void drawFllowerPath(Path path, List points) {
		if (points.size() > 1) {
			for (int j = 0; j < points.size(); j++) {

				CPoint point = points.get(j);

				if (j == 0) {
					CPoint next = points.get(j + 1);
					point.dx = ((next.x - point.x) * intensity);
					point.dy = ((next.y - point.y) * intensity);
				} else if (j == points.size() - 1) {
					CPoint prev = points.get(j - 1);
					point.dx = ((point.x - prev.x) * intensity);
					point.dy = ((point.y - prev.y) * intensity);
				} else {
					CPoint next = points.get(j + 1);
					CPoint prev = points.get(j - 1);
					point.dx = ((next.x - prev.x) * intensity);
					point.dy = ((next.y - prev.y) * intensity);
				}

				// create the cubic-spline path
				if (j == 0) {
					path.moveTo(point.x, point.y);
				} else {
					CPoint prev = points.get(j - 1);
					path.cubicTo(prev.x + prev.dx, (prev.y + prev.dy),
							point.x - point.dx, (point.y - point.dy),
							point.x, point.y);
				}
			}
		}
	}

	/**
	 * 曲線搖擺的幅度
	 */
	private int range = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 70, getResources().getDisplayMetrics());

	/**
	 * 畫路徑
	 * 
	 * @param point
	 * @return
	 */
	private List builderPath(CPoint point) {
		List points = new ArrayList();
		Random random = new Random();
		for (int i = 0; i < quadCount; i++) {
			if (i == 0) {
				points.add(point);
			} else {
				CPoint tmp = new CPoint(0, 0);
				if (random.nextInt(100) % 2 == 0) {
					tmp.x = point.x + random.nextInt(range);
				} else {
					tmp.x = point.x - random.nextInt(range);
				}
				tmp.y = (int) (height / (float) quadCount * i);
				points.add(tmp);
			}
		}
		return points;
	}

	/**
	 * 畫筆
	 */
	private Paint mPaint;

	/**
	 * 測量路徑的坐標位置
	 */
	private PathMeasure pathMeasure = null;

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);

		drawFllower(canvas, fllowers1);
		drawFllower(canvas, fllowers2);
		drawFllower(canvas, fllowers3);

	}

	/**
	 * 高度往上偏移量,把開始點移出屏幕頂部
	 */
	private float dy = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,40, getResources().getDisplayMetrics());
	
	/**
	 * 
	 * @param canvas
	 * @param fllowers
	 */
	private void drawFllower(Canvas canvas, List fllowers) {
		for (Fllower fllower : fllowers) {
			float[] pos = new float[2];
			canvas.drawPath(fllower.getPath(),mPaint);
			pathMeasure.setPath(fllower.getPath(), false);
			pathMeasure.getPosTan(height * fllower.getValue(), pos, null);
			canvas.drawCircle(pos[0], pos[1], 10, mPaint);
//			Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resId);
//			canvas.drawBitmap(bitmap, pos[0], pos[1] - dy, null);
//			bitmap.recycle();
		}
	}

	public void startAnimation() {
		ObjectAnimator mAnimator1 = ObjectAnimator.ofFloat(this, phase1, 0f,
				1f);
		mAnimator1.setDuration(time);
		mAnimator1.addUpdateListener(this);
		mAnimator1.start();
		mAnimator1.setInterpolator(new AccelerateInterpolator(1f));

		ObjectAnimator mAnimator2 = ObjectAnimator.ofFloat(this, phase2, 0f,
				1f);
		mAnimator2.setDuration(time);
		mAnimator2.addUpdateListener(this);
		mAnimator2.start();
		mAnimator2.setInterpolator(new AccelerateInterpolator(1f));
		mAnimator2.setStartDelay(delay);

		ObjectAnimator mAnimator3 = ObjectAnimator.ofFloat(this, phase3, 0f,
				1f);
		mAnimator3.setDuration(time);
		mAnimator3.addUpdateListener(this);
		mAnimator3.start();
		mAnimator3.setInterpolator(new AccelerateInterpolator(1f));
		mAnimator3.setStartDelay(delay * 2);
	}

	/**
	 * 跟新小球的位置
	 * 
	 * @param value
	 * @param fllowers
	 */
	private void updateValue(float value, List fllowers) {
		for (Fllower fllower : fllowers) {
			fllower.setValue(value);
		}
	}

	/**
	 * 動畫改變回調
	 */
	@Override
	public void onAnimationUpdate(ValueAnimator arg0) {

		updateValue(getPhase1(), fllowers1);
		updateValue(getPhase2(), fllowers2);
		updateValue(getPhase3(), fllowers3);
		Log.i(tag, getPhase1() + );
		invalidate();
	}

	public float getPhase1() {
		return phase1;
	}

	public void setPhase1(float phase1) {
		this.phase1 = phase1;
	}

	public float getPhase2() {
		return phase2;
	}

	public void setPhase2(float phase2) {
		this.phase2 = phase2;
	}

	public float getPhase3() {
		return phase3;
	}

	public void setPhase3(float phase3) {
		this.phase3 = phase3;
	}

	private String tag = this.getClass().getSimpleName();

	private class CPoint {

		public float x = 0f;
		public float y = 0f;

		/** x-axis distance */
		public float dx = 0f;

		/** y-axis distance */
		public float dy = 0f;

		public CPoint(float x, float y) {
			this.x = x;
			this.y = y;
		}
	}

}
 

 

 

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved