Android屬性動畫、函數動畫

**

Android動畫集錦(屬性動畫)

**

先看效果圖:
多個動畫

1、第一個圖片的閃動光暈效果;
2、雙重繪製圓形,利用線程定期畫弧度;
3、利用線性函數繪製同心圓從0°到360°完整的路徑;
4、將指定的view在指定的拋物線路徑上做循環動畫;
5、周期函數動畫,x方向線性變化,y方向爲周期函數:
y = 120 * sin(0.01 * π * x) + 200,從起始點(0,200)到結束點(600,200)之間的動畫,並在動畫過程中繪製路徑和圓形。

周期函數動畫代碼如下:

/**
 * TypeEvaluatorView  2019-11-19
 */
public class TypeEvaluatorView extends View {

	private Paint circlePaint = new Paint();
	private P currentP;
	private float mRadius = 15f;
	private int width;
	private int height;
	private Path path = new Path();
	private Paint pathPaint = new Paint();
	private static boolean isFirst = true;
	private static int repeatCount = 0;
	private int color[] = { 0xffffffff, 0xFFFF00FF, 0xffffff00, 0xff33ffff };

	public TypeEvaluatorView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public TypeEvaluatorView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	public TypeEvaluatorView(Context context) {
		super(context);
	}

	public void startAnimation() {
		P startP = new P(0, getHeight() / 2);
		P endP = new P(getWidth(), getHeight() / 2);
		// 第一次畫路徑時,將path的起始位置設置爲開始位置
		if (isFirst) {
			path.moveTo(0, getHeight() / 2);
		}
		ValueAnimator animator = ValueAnimator.ofObject(new OscillationEvaluator(), startP, endP);
		animator.setDuration(5000).setRepeatCount(Integer.MAX_VALUE);
		animator.setRepeatMode(Animation.REVERSE);
		animator.addUpdateListener(new AnimatorUpdateListener() {

			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				// 拿到當前運動到的點位置
				currentP = (P) animation.getAnimatedValue();
				// 在起點和終點之間收集繪製路徑
				path.lineTo(currentP.getX(), currentP.getY());
				// 重繪view
				invalidate();
			}
		});
		animator.addListener(new AnimatorListener() {

			@Override
			public void onAnimationStart(Animator animation) {

			}

			@SuppressLint("NewApi")
			@Override
			public void onAnimationRepeat(Animator animation) {
				isFirst = false;
				repeatCount++;
				// 重新設置path路徑
				path.reset();
				// 根據動畫的重複,設置路徑的起點和終點
				if (repeatCount % 2 == 0) {
					// 偶數次起點在開始位置
					path.moveTo(0, height / 2);
				} else {
					// 奇數次,起點在結束位置
					path.moveTo(getWidth(), height / 2);
				}
			}

			@Override
			public void onAnimationEnd(Animator animation) {

			}

			@Override
			public void onAnimationCancel(Animator animation) {

			}
		});
		animator.setInterpolator(new LinearInterpolator());// 設置插值器
		animator.start();
	}


	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		width = getWidth();
		height = getHeight();

		// path.moveTo(0, height / 2);//炫酷的扇子形狀

		Paint linePaint = new Paint();
		linePaint.setStyle(Style.STROKE);
		linePaint.setAntiAlias(true);
		linePaint.setStrokeWidth(3f);
		linePaint.setColor(color[0]);
		// 中間白線
		canvas.drawLine(0, height / 2, width, height / 2, linePaint);

		pathPaint.setStyle(Style.STROKE);
		pathPaint.setAntiAlias(true);
		pathPaint.setStrokeWidth(5f);
		pathPaint.setColor(color[0]);

		circlePaint.setStyle(Style.FILL);
		circlePaint.setAntiAlias(true);
		if (currentP == null) {
			startAnimation();
		}
		// 設置不同的四種顏色
		if (repeatCount % 4 == 0) {
			circlePaint.setColor(color[0]);
			pathPaint.setColor(color[0]);
		} else if (repeatCount % 4 == 1) {
			pathPaint.setColor(color[1]);
			circlePaint.setColor(color[1]);
		} else if (repeatCount % 4 == 2) {
			pathPaint.setColor(color[2]);
			circlePaint.setColor(color[2]);
		} else {
			pathPaint.setColor(color[3]);
			circlePaint.setColor(color[3]);
		}
		// 畫路徑
		canvas.drawPath(path, pathPaint);
		// 第一次不畫圓
		if (repeatCount >= 1) {
			canvas.drawCircle(currentP.getX(), currentP.getY(), mRadius, circlePaint);
		}
	}

	class P {
		private float x;
		private float y;

		/**
		 * @param x
		 * @param y
		 */
		public P(float x, float y) {
			super();
			this.x = x;
			this.y = y;
		}

		/**
		 * @return the x
		 */
		public float getX() {
			return x;
		}

		/**
		 * @param x
		 *            the x to set
		 */
		public void setX(float x) {
			this.x = x;
		}

		/**
		 * @return the y
		 */
		public float getY() {
			return y;
		}

		/**
		 * @param y
		 *            the y to set
		 */
		public void setY(float y) {
			this.y = y;
		}

	}

	class OscillationEvaluator implements TypeEvaluator<P> {

		@Override
		public P evaluate(float fraction, P startValue, P endValue) {
			P startP = (P) startValue;
			P endP = (P) endValue;
			float x = startP.getX() + fraction * (endP.getX() - startP.getX());// x座標線性變化
			float y = 120 * (float) (Math.sin(0.01 * Math.PI * x)) + getHeight() / 2;// y座標取相對應函數值
			return new P(x, y);
		}

	}

}

將此自定義的view放在xml佈局中即可,view的寬爲600dp,高爲400dp。


拋物線動畫代碼:

從(0,0)到(200,200)之間的動畫軌跡

public void beginTranslateAnimation(final View view) {
		ArrayList<Float> xvalues = new ArrayList<Float>();
		xvalues.add(0f);
		xvalues.add(200f);
		ArrayList<Float> yvalues = new ArrayList<Float>();
		yvalues.add(0f);
		yvalues.add(200f);
		final ObjectAnimator translateX = ObjectAnimator.ofObject(view, "translationX",
				new CustomXTypeEvaluator(), xvalues.toArray());
		final ObjectAnimator translateY = ObjectAnimator.ofObject(view, "translationY",
				new CustomYTypeEvaluator(), yvalues.toArray());
		translateX.setRepeatCount(Integer.MAX_VALUE);
		translateX.setRepeatMode(ObjectAnimator.REVERSE);
		translateX.setInterpolator(new LinearInterpolator());
		translateY.setInterpolator(new AccelerateInterpolator());
		translateY.setRepeatCount(Integer.MAX_VALUE);
		translateY.setRepeatMode(ObjectAnimator.REVERSE);
		// translateX.setInterpolator(new BounceInterpolator());
		// translateX.setInterpolator(new CycleInterpolator(0.6f));
		AnimatorSet animatorSet = new AnimatorSet();

		animatorSet.playTogether(translateX, translateY);
		animatorSet.setDuration(1000);
		animatorSet.start();
		view.invalidate();
	}

x方向線性運動,CustomXTypeEvaluator.java:

/**
 * TypeEvaluator 2019-11-26
 */
public class CustomXTypeEvaluator implements TypeEvaluator<Float> {

	@Override
	public Float evaluate(float f, Float startValue, Float endValue) {
		float x = startValue + f * (endValue - startValue);
		// float x = startValue * 1.2f;
		return x;
	}

}

y方向拋物線運動,CustomYTypeEvaluator.java:

/**
 * TypeEvaluator 2019-11-26
 */
public class CustomYTypeEvaluator implements TypeEvaluator<Float> {

	@Override
	public Float evaluate(float f, Float startValue, Float endValue) {
		float y = startValue + f * f * (endValue - startValue);
		return y;
	}

}

獲取源代碼加VX:13361000135

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章