豆瓣加载动画实现
最終效果如下
ValueAnimator類API 簡介
ofFloat(float… values) 構建ValueAnimator,設置動畫的浮點值,需要設置2個以上的值
setDuration(long duration) 設置動畫時長,默認的持續時間為300毫秒。
setInterpolator(TimeInterpolator value) 設置動畫的線性非線性運動,默認AccelerateDecelerateInterpolator
addUpdateListener(ValueAnimator.AnimatorUpdateListener listener) 監聽動畫屬性每一幀的變化
分解步驟,計算一下總共需要的角度:
1、一個笑臉,x軸下方的圓弧旋轉135°,覆蓋2個點,此過程中圓弧增加45°
2、畫布旋轉135°,此過程中圓弧增加45°
3、畫布旋轉360°,此過程中圓弧減少360/5度
4、畫布旋轉90°,此過程中圓弧減少90/5度
5、畫布旋轉135°,釋放覆蓋的2個點
實現
package com.zj.test;import android.animation.TimeInterpolator; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.util.AttributeSet; import android.view.View; import android.view.animation.DecelerateInterpolator;/*** Created by jjx on 2016/5/28.*/ public class customView extends View{// public customView(Context context, AttributeSet attrs, int defStyleAttr) { // super(context, attrs, defStyleAttr); // // initAnimator(animatorDuration); // mPaint=new Paint(); // mPaint.setStyle(Paint.Style.STROKE);//設置畫筆樣式為描邊,如果已經設置,可以忽略 // mPaint.setColor(Color.GREEN); // mPaint.setStrokeWidth(10); // }float Width;float Height;public customView(Context context, AttributeSet attrs) {super(context, attrs);initAnimator(animatorDuration);mPaint=new Paint();mPaint.setStyle(Paint.Style.STROKE);//設置畫筆樣式為描邊,如果已經設置,可以忽略mPaint.setColor(Color.GREEN);mPaint.setStrokeWidth(10);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);Width=MeasureSpec.getSize(widthMeasureSpec);mViewWidth=Width;Height=MeasureSpec.getSize(heightMeasureSpec);}Paint mPaint;float mViewWidth;@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.translate(Width/2,Height/2);doubanAnimator(canvas, mPaint);}private ValueAnimator animator;private float animatedValue;private long animatorDuration = 5000;private TimeInterpolator timeInterpolator = new DecelerateInterpolator();private void initAnimator(long duration){if (animator !=null &&animator.isRunning()){animator.cancel();animator.start();}else {animator=ValueAnimator.ofFloat(0,855).setDuration(duration);animator.setInterpolator(timeInterpolator);animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {animatedValue = (float) animation.getAnimatedValue();invalidate();}});animator.start();}}private void doubanAnimator(Canvas canvas, Paint mPaint){mPaint.setStyle(Paint.Style.STROKE);//描邊mPaint.setStrokeCap(Paint.Cap.ROUND);//圓角筆觸mPaint.setColor(Color.rgb(97, 195, 109));mPaint.setStrokeWidth(15);float point = Math.min(mViewWidth,mViewWidth)*0.06f/2;float r = point*(float) Math.sqrt(2);RectF rectF = new RectF(-r,-r,r,r);canvas.save();// rotateif (animatedValue>=135){canvas.rotate(animatedValue-135);}// draw mouthfloat startAngle=0, sweepAngle=0;if (animatedValue<135){startAngle = animatedValue +5;sweepAngle = 170+animatedValue/3;}else if (animatedValue<270){startAngle = 135+5;sweepAngle = 170+animatedValue/3;}else if (animatedValue<630){startAngle = 135+5;sweepAngle = 260-(animatedValue-270)/5;}else if (animatedValue<720){startAngle = 135-(animatedValue-630)/2+5;sweepAngle = 260-(animatedValue-270)/5;}else{startAngle = 135-(animatedValue-630)/2-(animatedValue-720)/6+5;sweepAngle = 170;}canvas.drawArc(rectF,startAngle,sweepAngle,false,mPaint);// draw eyecanvas.drawPoints(new float[]{-point,-point,point,-point},mPaint);canvas.restore();}}布局文件
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.zj.test.MainActivity"><com.zj.test.customView android:layout_width="match_parent"android:layout_height="match_parent"></com.zj.test.customView> </RelativeLayout>參考鏈接
自定義View——Canvas與ValueAnimator – Idtk
總結
- 上一篇: win10下安装node
- 下一篇: 线性-LR-softmax傻傻分不清楚