动画核心:
1.主要考验动画的拆分,然后分析动画.
2.判断一个动画好与坏,主要是看动画的平滑程度,而能解决动画不平滑需要做很多处理,这就考验做动画的人的能力.
3.mPaint.setStrokeCap(Paint.Cap.ROUND)画笔的笔刷 是方形 还是圆形,看平滑程度.
4.两种控制动画的手段
(1) onDraw{
switch(status){
case 0 :
break;
case 0 :
break;
case 0 :
break;
case 0 :
break;
case 0 :
break;
}
}
(2)onDraw{
if(mFraction> 0.3){
}else{
}
}
5.上述两种方式可以搭配工具类使用.会更好.
6.主要将动画分解,然后学会动画.
package com.example.administrator.animationworkdemo.views;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;
/**
* Created by SuperD on 2017/2/28.
* Demo10中的View
*/
public class SearchAnimView2 extends View implements View.OnClickListener {
private static final int LINE_WIDTH = 9;
private static final int LINE_COLOR = Color.BLACK;
private static final int DEFAULT_POINT_SIZE = 3;
private static final int DEFAULT_DURATION = 3000;
private Paint mPaint;
private Paint mArcPaint;
private boolean isDotShowing = true;
private float mWidth;
private float mHeight;
private float mCenterX;
private float mCenterY;
private float mCircleRadius;
private RectF mRectF;
private Path mPath;
private Path mArcPath;
private PathMeasure mPathMeasure;
private float mPathLength;
private float mCurrentPos[] = new float[2];
private float mCurrentTan[] = new float[2];
private ValueAnimator mAnim;
private float mFraction;
public SearchAnimView2(Context context) {
this(context, null);
}
public SearchAnimView2(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SearchAnimView2(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(LINE_WIDTH);
mPaint.setColor(LINE_COLOR);
mArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mArcPaint.setStyle(Paint.Style.FILL);
mArcPaint.setColor(Color.WHITE);
mPath = new Path();
mPathMeasure = new PathMeasure();
mArcPath = new Path();
mAnim = ValueAnimator.ofFloat(1f, 100f);
mAnim.setDuration(DEFAULT_DURATION);
mAnim.setInterpolator(new LinearInterpolator());
mAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mFraction = animation.getAnimatedFraction();
invalidate();
}
});
setOnClickListener(this);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
mCenterX = mWidth / 2;
mCenterY = mHeight / 2;
mCircleRadius = mWidth / 4;
mRectF = new RectF(
mCenterX - 0.95f * mCircleRadius,
mCenterY - 0.95f * mCircleRadius,
mCenterX + 0.95f * mCircleRadius,
mCenterY + 0.95f * mCircleRadius);
mPath.moveTo(mCenterX + 2.2f * mCircleRadius / (float) Math.sqrt(2),
mCenterY + 2.2f * mCircleRadius / (float) Math.sqrt(2));
mPath.lineTo(mCenterX, mCenterY);
mPath.lineTo(mCenterX - 0.45f * mCircleRadius * (float) Math.sqrt(3),
mCenterY + 0.45f * mCircleRadius);
mPath.lineTo(mCenterX - 0.45f * mCircleRadius * (float) Math.sqrt(3),
mCenterY - 0.45f * mCircleRadius);
mPath.lineTo(mCenterX + 0.45f * mCircleRadius * (float) Math.sqrt(3),
mCenterY);
mPath.lineTo(mCenterX, mCenterY);
mPath.lineTo(mCenterX + 2.2f * mCircleRadius / (float) Math.sqrt(2),
mCenterY + 2.2f * mCircleRadius / (float) Math.sqrt(2));
mPathMeasure.setPath(mPath, false);
mPathLength = mPathMeasure.getLength();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float sin45 = (float) Math.sin(Math.PI / 4);
if (mFraction <= 0.2) {
canvas.drawCircle(mCenterX, mCenterY, mCircleRadius - mCircleRadius * mFraction, mPaint);
canvas.drawLine(mCenterX + mCircleRadius * sin45 + 1.2f * mCircleRadius * sin45 * mFraction / 0.2f,
mCenterY + mCircleRadius * sin45 + 1.2f * mCircleRadius * sin45 * mFraction / 0.2f,
mCenterX + 2.2f * mCircleRadius * sin45,
mCenterY + 2.2f * mCircleRadius * sin45,
mPaint);
} else if (mFraction <= 0.8) {
mPathMeasure.getPosTan(0 + mPathLength * (mFraction - 0.2f) / 0.6f, mCurrentPos, mCurrentTan);
if (mCurrentPos[1] == mCenterY &&
mCurrentPos[0] <= mCenterX + mCircleRadius / 3 &&
mCurrentPos[0] >= mCenterX - mCircleRadius / 3) {
if (isDotShowing) {
isDotShowing = false;
} else {
canvas.drawCircle(mCurrentPos[0], mCurrentPos[1], DEFAULT_POINT_SIZE, mPaint);
isDotShowing = true;
}
} else {
canvas.drawCircle(mCurrentPos[0], mCurrentPos[1], DEFAULT_POINT_SIZE, mPaint);
}
if (mFraction <= 0.3) {
canvas.drawCircle(mCenterX, mCenterY,
0.8f * mCircleRadius + mCircleRadius * 2 * (mFraction - 0.2f), mPaint);
} else {
canvas.drawCircle(mCenterX, mCenterY, mCircleRadius, mPaint);
}
if (mFraction <= 0.35 && mFraction > 0.3) {
canvas.drawArc(mRectF, 45 - 55 * (mFraction - 0.3f) / 0.05f,
110 * (mFraction - 0.3f) / 0.05f, false, mArcPaint);
} else if (mFraction <= 0.4 && mFraction > 0.35) {
canvas.drawArc(mRectF, 45 - 55 / 0.05f * (0.4f - mFraction),
110 / 0.05f * (0.4f - mFraction), false, mArcPaint);
}
if (mFraction <= 0.75 && mFraction > 0.7) {
mArcPath.reset();
mArcPath.moveTo(mCenterX + mCircleRadius, mCenterY);
mArcPath.cubicTo(mCenterX + mCircleRadius + 8 * (mFraction - 0.7f) / 0.05f,
mCenterY + mCircleRadius / 2 + 8 * (mFraction - 0.7f) / 0.05f,
mCenterX + mCircleRadius / 2 + 8 * (mFraction - 0.7f) / 0.05f,
mCenterY + mCircleRadius + 8 * (mFraction - 0.7f) / 0.05f,
mCenterX,
mCenterY + mCircleRadius);
canvas.drawPath(mArcPath, mPaint);
} else if (mFraction <= 0.8 && mFraction > 0.75) {
mArcPath.reset();
mArcPath.moveTo(mCenterX + mCircleRadius, mCenterY);
mArcPath.cubicTo(mCenterX + mCircleRadius + 8 * (0.8f - mFraction) / 0.05f,
mCenterY + mCircleRadius / 2 + 8 * (0.8f - mFraction) / 0.05f,
mCenterX + mCircleRadius / 2 + 8 * (0.8f - mFraction) / 0.05f,
mCenterY + mCircleRadius + 8 * (0.8f - mFraction) / 0.05f,
mCenterX,
mCenterY + mCircleRadius);
canvas.drawPath(mArcPath, mPaint);
}
} else {
canvas.drawCircle(mCenterX, mCenterY, mCircleRadius, mPaint);
canvas.drawLine(mCenterX + 2.2f * mCircleRadius * sin45 - 1.2f * mCircleRadius * sin45 * (mFraction - 0.8f) / 0.2f,
mCenterY + 2.2f * mCircleRadius * sin45 - 1.2f * mCircleRadius * sin45 * (mFraction - 0.8f) / 0.2f,
mCenterX + 2.2f * mCircleRadius * sin45,
mCenterY + 2.2f * mCircleRadius * sin45
, mPaint);
}
}
@Override
public void onClick(View v) {
if (!mAnim.isRunning()) {
mAnim.start();
}
}
}