最近研究了一些动画效果 这里就分享给大家吧 gif效果不太好 因为压缩了一下 凑合看看 哈哈
1.布局中有两个自定义类(外围整体 用相对布局就能看到效果)
2.画线类
public class MySquare extends View {
private static final float PER_LINE_MAX_Top = 40;
private static final float PER_LINE_MAX_Rit = 20;
private Context mContext;
private Paint paint;
private Paint processPaint;
private Paint textPaint;
private Canvas canvas;
private int currentPogress;
private int strokeColor = Color.BLACK;
private float strokeWith = 2.0f;
private int progressColor = Color.RED;
private int textColor = Color.BLUE;
private float textSize = 10.0f;
public MySquare(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mContext = context;
initValue(attrs);
}
private void initValue(AttributeSet attrs) {
TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.SquareProcessView);
currentPogress = typedArray.getInteger(R.styleable.SquareProcessView_currentPogress, 0);
strokeColor = typedArray.getColor(R.styleable.SquareProcessView_strokeColor, ContextCompat.getColor(mContext, R.color.colorPrimary));
strokeWith = typedArray.getDimension(R.styleable.SquareProcessView_strokeWith, strokeWith);
progressColor = typedArray.getColor(R.styleable.SquareProcessView_progressColor, ContextCompat.getColor(mContext, R.color.colorAccent));
textColor = typedArray.getColor(R.styleable.SquareProcessView_textColor, ContextCompat.getColor(mContext, R.color.colorAccent));
textSize = typedArray.getDimension(R.styleable.SquareProcessView_textSize, textSize);
initPaints();
}
private void initPaints() {
paint = new Paint();
paint.setColor(strokeColor);
paint.setStrokeWidth(strokeWith);
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
initProcessPaint();
initTextPaint();
}
private void initProcessPaint() {
processPaint = new Paint();
processPaint.setColor(progressColor);
processPaint.setStrokeWidth(strokeWith);
processPaint.setAntiAlias(true);
processPaint.setStyle(Paint.Style.STROKE);
}
private void initTextPaint() {
textPaint = new Paint();
textPaint.setColor(textColor);
textPaint.setAntiAlias(true);
textPaint.setStyle(Paint.Style.STROKE);
textPaint.setTextSize(textSize);
}
public void setCurrentPogress(int currentPogress) {
this.currentPogress = currentPogress;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
this.canvas = canvas;
/*画图*/
drawSquare();
/*画圆*/
drawrec();
/*画线*/
drawProcessSquare(currentPogress);
}
private void drawrec() {
Paint mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(strokeWith);
mPaint.setColor(Color.rgb(79,80,101));
canvas.drawCircle(canvas.getWidth() / 2, 10, 10, mPaint);
}
/**
* 画线
*/
private void drawSquare() {
drawRightLine();
}
private void drawRightLine() {
Path path = new Path();
/*把坐标移动到右上角*/
path.moveTo(canvas.getWidth() / 2, 20);
path.lineTo(canvas.getWidth() / 2, canvas.getHeight()-20);
canvas.drawPath(path, paint);
}
/**
* 画进度
*/
private void drawProcessSquare(int progress) {
float rightProcess = 0;
rightProcess = progress ;
drawProgressRightLine(rightProcess);
}
private void drawProgressRightLine(float progress) {
Path path = new Path();
/*把坐标移动到右上角*/
path.moveTo(canvas.getWidth() / 2, 20);
path.lineTo(canvas.getWidth() / 2, canvas.getHeight() / PER_LINE_MAX_Rit * progress);
canvas.drawPath(path, processPaint);
}
}
3.画圆类
public class Yuan extends View {
/**
* view的宽度
*/
private int width;
/**
* view的高度
*/
private int height;
/**
* 圆角半径
*/
private int circleAngle;
/**
* 默认两圆圆心之间的距离=需要移动的距离
*/
private int default_two_circle_distance;
/**
* 两圆圆心之间的距离
*/
private int two_circle_distance;
/**
* 背景颜色
*/
private int bg_color = 0xffbc7d53;
/**
* 按钮文字字符串
*/
private String buttonString = "确认完成";
/**
* 动画执行时间
*/
private int duration = 1000;
/**
* view向上移动距离
*/
private int move_distance = 300;
/**
* 圆角矩形画笔
*/
private Paint paint;
/**
* 文字画笔
*/
private Paint textPaint;
/**
* 对勾(√)画笔
*/
private Paint okPaint;
/**
* 文字绘制所在矩形
*/
private Rect textRect = new Rect();
/**
* 动画集
*/
private AnimatorSet animatorSet = new AnimatorSet();
/**
* 绘制对勾(√)的动画
*/
private ValueAnimator animator_draw_ok;
/**
* 是否开始绘制对勾
*/
private boolean startDrawOk = false;
/**
* 根据view的大小设置成矩形
*/
private RectF rectf = new RectF();
/**
* 路径--用来获取对勾的路径
*/
private Path path = new Path();
/**
* 取路径的长度
*/
private PathMeasure pathMeasure;
/**
* 对路径处理实现绘制动画效果
*/
private PathEffect effect;
private Canvas canvas;
private float strokeWith = 2.0f;
public Yuan(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initPaint();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
this.canvas = canvas;
/*画圆*/
drawrec();
canvas.drawPath(path, okPaint);
}
private void drawrec() {
Paint mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(strokeWith);
mPaint.setColor(Color.rgb(20, 164, 101));
canvas.drawCircle(canvas.getWidth() / 2, 50, 50, mPaint);
}
/**
* 初始化所有动画
*/
private void initAnimation() {
set_draw_ok_animation();
animatorSet
.play(animator_draw_ok);
}
/**
* 绘制对勾的动画
*/
private void set_draw_ok_animation() {
animator_draw_ok = ValueAnimator.ofFloat(1, 0);
animator_draw_ok.setDuration(duration);
animator_draw_ok.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
startDrawOk = true;
float value = (Float) animation.getAnimatedValue();
effect = new DashPathEffect(new float[]{pathMeasure.getLength(), pathMeasure.getLength()}, value * pathMeasure.getLength());
okPaint.setPathEffect(effect);
invalidate();
}
});
}
private void initPaint() {
okPaint = new Paint();
okPaint.setStrokeWidth(10);
okPaint.setStyle(Paint.Style.STROKE);
okPaint.setAntiAlias(true);
okPaint.setColor(Color.WHITE);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
width = w;
height = h;
default_two_circle_distance = (w - h) / 2;
initOk();
initAnimation();
start();
}
/**
* 绘制对勾
*/
private void initOk() {
//对勾的路径
path.moveTo(default_two_circle_distance + height / 9 * 3, height / 9 * 3);
path.lineTo(default_two_circle_distance + height / 2, height / 8 * 4);
path.lineTo(default_two_circle_distance + height / 4 * 3, height / 4);
pathMeasure = new PathMeasure(path, true);
}
/**
* 启动动画
*/
public void start() {
animatorSet.start();
}
}
最后附上我们的activity中的代码 大功告成
public class Main2Activity extends AppCompatActivity {
private MySquare squareProgressView;
private MyHandnler myHandnler = new MyHandnler(this);
private int currentProcess;
private int currentProcessGou;
public WeakReference weakReference;
private Yuan yuan;
Animation animation;
Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
squareProgressView = (MySquare) findViewById(R.id.sqareProcess);
animation = AnimationUtils.loadAnimation(this, R.anim.anim_small);
yuan = (Yuan) findViewById(R.id.yuan);
try {
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
button= findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myHandnler.sendEmptyMessage(1);
}
});
}
class MyHandnler extends Handler {
public MyHandnler(Main2Activity mainActivity) {
weakReference = new WeakReference<>(mainActivity);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
/*圈线*/
if (msg.what == 1) {
if (weakReference.get().currentProcess <= 100) {
weakReference.get().currentProcess++;
weakReference.get().squareProgressView.setCurrentPogress(weakReference.get().currentProcess);
sendEmptyMessageDelayed(1, 0);
}
if (weakReference.get().currentProcess == 40) {
yuan.setVisibility(View.VISIBLE);
yuan.startAnimation(animation);
sendEmptyMessageDelayed(3, 0);
}
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
myHandnler.removeCallbacksAndMessages(null);
}
}
android:fillAfter="true"
android:fillBefore="true"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:interpolator="@android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="1"
android:repeatMode="reverse"
android:toXScale="1.5"
android:toYScale="1.5"/>