您的位置:首页 > 其它

圆形展开

2015-07-04 14:00 127 查看

效果

在加载数据时,界面上需要一个进度条提示用户等待。当数据加载完成后,需要隐藏进度条。在隐藏时,可以使用一些效果,比如一个空心圆从中间开始,一点点的扩大,显露出下面的内容。如:



原理

在展示时,其实是画一个空心圆,内圆的半径不断地增大,这样就类似于一个扩散效果。

在画空心圆时,需要不断地调整笔画的宽度,这样就能保证外面一层始终是被遮盖住的。

代码

package com.example.hufeng.demo;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.view.animation.OvershootInterpolator;

public class MyLinearLayout extends View {
private int radius = 90;
private int smallRadius = 15;
private Paint circlePaint;
private Paint spreadPaint;
private static final int STATE_ROTATION = 1;
private static final int STATE_MERGE = 2;
private static final int STATE_SPREAD = 3;
private int mCurrState = STATE_ROTATION;
private int startAngle = 0;
private float tempRadius;
private ValueAnimator rotationAnimator, mergeAnimator;
private int[] mColors = new int[]{Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.GRAY, Color.BLACK};
private float centerX, centerY,length;

public MyLinearLayout(Context context, AttributeSet set) {
super(context, set);
init();
startRotation();
}

private void init() {
circlePaint = new Paint();
circlePaint.setStyle(Paint.Style.FILL);
circlePaint.setAntiAlias(true);
spreadPaint = new Paint();
spreadPaint.setStyle(Paint.Style.STROKE);//只画边框,这样能保证中间是空白,从而画出同心圆
spreadPaint.setAntiAlias(true);
spreadPaint.setColor(Color.rgb(0xaa, 0x55, 0x88));//与该控件的背影色一样
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
centerX = getWidth() / 2.0f;
centerY = getHeight() / 2.0f;
length = (float)Math.sqrt((getWidth() * getWidth())+(getHeight() * getHeight()))/2;
}

private void startRotation() {
rotationAnimator = ValueAnimator.ofInt(0, 360);
rotationAnimator.setInterpolator(new LinearInterpolator());
rotationAnimator.setDuration(1000);
rotationAnimator.setRepeatCount(ValueAnimator.INFINITE);
rotationAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
startAngle = (Integer) valueAnimator.getAnimatedValue();
invalidate();
}
});
rotationAnimator.start();
}

@Override
protected void onDraw(Canvas canvas) {
switch (mCurrState) {
case STATE_MERGE:
canvas.drawColor(Color.rgb(0xaa, 0x55, 0x88));//重新绘上背影色
drawMerge(canvas);
break;
case STATE_ROTATION:
canvas.drawColor(Color.rgb(0xaa, 0x55, 0x88));
drawRotation(canvas);
break;
case STATE_SPREAD:
drawSpread(canvas);
break;
}

}

private void drawSpread(Canvas canvas) {
// 圆的半径=内环小圆半径+画笔宽度的一半
canvas.drawCircle(centerX,centerY,tempRadius+spreadPaint.getStrokeWidth()/2,spreadPaint);
}

private void drawMerge(Canvas canvas) {
for (int x = 0; x < mColors.length; x++) {
double rotation = Math.toRadians(x * 60 + startAngle);
circlePaint.setColor(mColors[x]);
double cx = centerX + tempRadius * Math.cos(rotation);//不断缩小半径,这样就显示出内聚效果
double cy = centerY + tempRadius * Math.sin(rotation);
canvas.drawCircle((float) cx, (float) cy, smallRadius, circlePaint);
}
}

private void drawRotation(Canvas canvas) {
for (int x = 0; x < mColors.length; x++) {
double rotation = Math.toRadians(x * 60 + startAngle);
circlePaint.setColor(mColors[x]);
double cx = centerX + radius * Math.cos(rotation);//不断改变角度,呈现出旋转效果
double cy = centerY + radius * Math.sin(rotation);
canvas.drawCircle((float) cx, (float) cy, smallRadius, circlePaint);
}
}

public void stop() {
mCurrState = STATE_MERGE;
rotationAnimator.cancel();
rotationAnimator = null;

mergeAnimator = ValueAnimator.ofFloat(0, radius);
mergeAnimator.setInterpolator(new OvershootInterpolator(6));
mergeAnimator.setDuration(1000);
mergeAnimator.setRepeatCount(0);
mergeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
tempRadius = (Float) valueAnimator.getAnimatedValue();
invalidate();
}
});
mergeAnimator.reverse();//反向开始,这样在内聚之间会往外扩展一下
mergeAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {

}

@Override
public void onAnimationEnd(Animator animator) {//结束后,开始画同心圆,展示加载出来的界面
startSpread();
}

@Override
public void onAnimationCancel(Animator animator) {

}

@Override
public void onAnimationRepeat(Animator animator) {

}
});
}

private void startSpread() {
mergeAnimator.cancel();
mergeAnimator = null;

mCurrState = STATE_SPREAD;
final ValueAnimator spreadAnimator = ValueAnimator.ofFloat(0,length);//半径由0到length
spreadAnimator.setDuration(1000);
spreadAnimator.setInterpolator(new LinearInterpolator());
spreadAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
tempRadius = (Float)valueAnimator.getAnimatedValue();//内环小圆半径
spreadPaint.setStrokeWidth(length - tempRadius);//设置画笔宽度
invalidate();
}
});
spreadAnimator.start();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: