当前位置: 代码迷 >> Android >> android 途径动画制作
  详细解决方案

android 途径动画制作

热度:60   发布时间:2016-04-28 02:12:33.0
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<Fllower> fllowers1 = new ArrayList<Fllower>();	private List<Fllower> fllowers2 = new ArrayList<Fllower>();	private List<Fllower> fllowers3 = new ArrayList<Fllower>();	/**	 * 动画播放的时间	 */	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<Fllower> 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<CPoint> 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<CPoint> 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<CPoint> builderPath(CPoint point) {		List<CPoint> points = new ArrayList<CPoint>();		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<Fllower> 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<Fllower> 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;		}	}}

4、项目地址

http://download.csdn.net/detail/hxc2008q/8473053




  相关解决方案