先看看效果吧,錄屏軟件錄出來的有點一卡一卡的,不曉得咋回事
源碼在這兒了,我也實在不曉得說啥子,畢竟第一次寫
public class MyLoadingAnimView extends View {
public MyLoadingAnimView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyLoadingAnimView(Context context) {
super(context);
init();
}
private RectF bigCircleRect;
private double alphaLengh;
private Paint bigCircle, smallCircle, eyeCircle;
private void init() {
initParams();
bigCircle = new Paint();
bigCircle.setColor(Color.RED);
bigCircle.setAntiAlias(true);
bigCircle.setStyle(Paint.Style.FILL);
smallCircle = new Paint();
smallCircle.setColor(Color.RED);
smallCircle.setAntiAlias(true);
smallCircle.setStyle(Paint.Style.FILL);
eyeCircle = new Paint();
eyeCircle.setColor(Color.WHITE);
eyeCircle.setAntiAlias(true);
eyeCircle.setStyle(Paint.Style.FILL);
}
/**
* 大圓半徑等於當前科繪製的(bottm-top)/2
*/
private int bigCircleRadious;
private int bigCx;
private int bigCy;
private int smallCircleRadious;
private int eyeCircleRadious;
/**
* 大圓半徑與小圓半徑的比例
*/
private double BigWithSmallScale = 4.0;
/**
* 大圓半徑與大圓上的圓半徑的比例
*/
private double BigWithEyeScale = 8.0;
//初始化各種參數
private void initParams() {
//各種內邊距
int paddIngLeft, paddingRight, paddingTop, paddingBottom;
//當前可繪製view的所在位置
int left, top, bottom;
paddIngLeft = getPaddingLeft();
paddingRight = getPaddingRight();
paddingTop = getPaddingTop();
paddingBottom = getPaddingBottom();
left = paddIngLeft;
top = paddingTop;
bottom = height - paddingBottom;
bigCircleRadious = (int) ((bottom - top) / 2.0);
bigCx = left + bigCircleRadious;
bigCy = top + bigCircleRadious;
smallCircleRadious = (int) (bigCircleRadious / BigWithSmallScale);
//透明度的總長度:大圓半徑距離三份+大圓圓心距離,+smallmarign*2
alphaLengh = bigCx + bigCircleRadious * 3 + smallMargin * 2;
eyeCircleRadious = (int) (bigCircleRadious / BigWithEyeScale);
//大圓所在矩形(左,上,右,下),這裏
bigCircleRect = new RectF(left, top, left + bigCircleRadious * 2, bottom);
}
/**
* 最大張開角度
*/
private double maxLegth = 200;
private void startAnim() {
ObjectAnimator animator = ObjectAnimator.ofInt(this, "progress", (int) maxLegth, (int) 0);
animator.setDuration(500);
animator.setRepeatCount(-1);
animator.setRepeatMode(ObjectAnimator.RESTART);
animator.setInterpolator(new LinearInterpolator());
animator.start();
}
private int currentAngle = 90;
void setProgress(int angle) {
currentAngle = angle;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int startAngle;
int sweepAngle;
if (currentAngle >= maxLegth / 2.0) {
//張開,
double angle = maxLegth - currentAngle;
startAngle = (int) (angle / 2);
sweepAngle = (int) (360 - angle);
} else {
//閉合
startAngle = currentAngle / 2;
sweepAngle = 360 - currentAngle;
}
canvas.drawArc(bigCircleRect, startAngle, sweepAngle, true, bigCircle);
//畫眼睛
double line = (bigCircleRadious * 3) / 5.0;
int eyeAngle = startAngle + 30;
int eyeX = (int) (bigCx + (Math.cos(eyeAngle * Math.PI / 180) * line));
int eyeY = (int) (bigCy - Math.sin(eyeAngle * Math.PI / 180) * line);
canvas.drawCircle(eyeX, eyeY, eyeCircleRadious, eyeCircle);
//畫第一個大圓
//第一個圓到大圓的距離,
int margin = (int) ((bigCircleRadious + smallMargin) * (currentAngle / maxLegth));
int cx1 = bigCx + margin;
smallCircle.setAlpha(getAlphaByCx(cx1));
canvas.drawCircle(cx1, bigCy, smallCircleRadious, smallCircle);
//畫第二個圓,第二個小圓最少要距離第一個圓一個bigCircleRadious的距離,這樣當大圓閉合的時候,纔不會進去
int cx2 = cx1 + bigCircleRadious + smallMargin;
smallCircle.setAlpha(getAlphaByCx(cx2));
canvas.drawCircle(cx2, bigCy, smallCircleRadious, smallCircle);
//畫第三個圓
int cx3 = cx2 + bigCircleRadious;
smallCircle.setAlpha(getAlphaByCx(cx3));
canvas.drawCircle(cx3, bigCy, smallCircleRadious, smallCircle);
if (!isStartAnim) {
startAnim();
isStartAnim = true;
}
}
/**
* 第一個小圓的距離和第二個小圓的距離
*/
private int smallMargin = 10;
private int getAlphaByCx(int cx1) {
double v = (alphaLengh - cx1) / (alphaLengh);
if (v < 0) {
v = 0;
} else if (v > 1) {
v = 1;
}
return (int) (v * 255);
}
private boolean isStartAnim = false;
private int widith = 100;
private int height = 30;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
initParams();
}
private int measureHeight(int heightMeasureSpec) {
int mode = MeasureSpec.getMode(heightMeasureSpec);
int size = MeasureSpec.getSize(heightMeasureSpec);
if (mode == MeasureSpec.EXACTLY) {
height = size;
} else {
if (mode == MeasureSpec.AT_MOST) {
height = Math.min(height, size);
}
}
return height;
}
private int measureWidth(int widthMeasureSpec) {
int mode = MeasureSpec.getMode(widthMeasureSpec);
int size = MeasureSpec.getSize(widthMeasureSpec);
if (mode == MeasureSpec.EXACTLY) {
widith = size;
} else {
if (mode == MeasureSpec.AT_MOST) {
widith = Math.min(widith, size);
}
}
return widith;
}
}
使用
<MyLoadingAnimView
android:layout_width="90dp"
android:layout_height="40dp" />