圆形展开

来源:互联网 发布:黑客帝国 知乎 编辑:程序博客网 时间:2024/04/28 18:36

效果

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


原理

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

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

代码

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();    }}


0 0
原创粉丝点击