圆形展开
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(); } }
相关文章推荐
- 使用Eclipse-Maven-git做Java开发(3)--Eclipse的安装和配置
- 安装oracle时swap过小安装失败
- 工程配置报错
- 学习WWDC的好资源!
- OAuth的机制原理讲解及开发流程
- 学习WWDC的好资源!
- 关于集合中迭代器中next()方法重复使用造成的错误
- SIP协议错误代码大全
- 论备份的重要性
- 关于Windows和Ubuntu的双系统修复问题
- cocos2dx clippingNode的实现原理
- ArcGIS10.1的安装问题
- css选择器优先级
- Hibernate的数据查找,添加!
- syntax error near unexpected token `then'问题的解决
- 关于label的各种细节处理
- stl之multiset容器的应用
- 高斯滤波在图像处理的基本应用
- [Effective Java]第三章 对所有对象都通用的方法
- 抽象类