弧形进度条(动画版)

本博客只要没有注明“转”,那么均为原创,转贴请注明本博客链接链接

我们先把问题分解为下面3个小问题。

1.如何画一个弧形

2.如何让弧形带有加载过程

3.如何让进度值随着圆弧一起转动

1.我们先看看进度条的样子

进度条很简单,一段弧,较长的白色的弧是100%时候的样子,较短红色的弧形是当前的进度。

这里我选用的是圆弧,弧度为240度,这里要注意一下,我选用的是角度制,之后计算三角函数的时候用的是弧度制,所以还需要进行转换。

现在我们知道我们要的进度条的样子了,制作也就有了思路。

先画一段弧形,240度的,然后再画一段弧形,图中进度为7/8=87.5%,那红色的弧形度数即为240 * 7/8 = 210度。我们只需要在开始的弧上再压上一段红色弧形即可。

上图中的弧形有个特点,两头是圆的。所以我们要先设置一下Paint

mPaint = new Paint();
mPaint.setAntiAlias(true); //消除锯齿
mPaint.setStyle(Paint.Style.STROKE); //绘制空心圆
mPaint.setStrokeWidth(mRingWidth); //设置进度条宽度
mPaint.setColor(mRingColor); //设置进度条颜色
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND); //设置圆角

当然我们有两个弧形,Paint设置类似。

下面我们开始画弧,代码大概是下面的样子

protected void onDraw(Canvas canvas) {
    canvas.drawArc(...); //完整弧形
    canvas.drawArc(...); //红色进度条弧形
    super.onDraw(canvas);
}

其中,drawArc是画弧的函数

public void drawArc (RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)

这里要对startAngle和sweepAngle参数进行解释一下。

这两个参数确定了角的两条边,startAngle是起始边,它以原点为中心顺时针旋转sweepAngle度后的位置为终边。这样就确定了一个角也就确定了一段圆弧。0度在3点钟方向,也就是x轴正方向。

上图的中灰色的那段弧形是多少度到多少度呢,我选择的是从-210度开始,到30度,幅度为240度。

下面我们可以开始画弧了。

先确定View的大小,这里我让View为一个正方形。取width和height都设置为Math.min(width, height)即可。

知道了View的大小,我们在这个正方形里面取一个小正方形放在正中间。两个正方形的距离就是弧形宽度的一半。然后Paint分别像内外各扩散1/2弧宽即可。

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);

    int sideLength = Math.min(widthSpecSize, heightSpecSize);
    setMeasuredDimension(sideLength, sideLength);
}

下面我们来画弧

private float mStart = -210;
private static final int FULL_ANGLE = 240;

@Override
protected void onDraw(Canvas canvas) {
    RectF mBigOval = new RectF(mRingWidth / 2, mRingWidth / 2,
            getWidth() - (mRingWidth + 1) / 2, getHeight() - (mRingWidth + 1) / 2);
    canvas.drawArc(mBigOval, mStart, FULL_ANGLE, false, mRemainderPaint); //灰色的弧
    canvas.drawArc(mBigOval, mStart, delta, false, mPaint); //红色的弧
    super.onDraw(canvas);
}

其中delta就是我们的进度,只不过delta的范围为0-240。

至此,如何制作弧形进度条已经讲完了,下面就是给它加个动画。

2.动画也很容易,我们只需要让delta从0一直变化到我们最终的进度即可

我们实现ValueAnimator.AnimatorUpdateListener接口。

public void setDelta(float delta) {
    this.delta = delta;
}

@Override
public void onAnimationUpdate(ValueAnimator animation) {
    invalidate();
}

改变delta之后,刷新View即可。

3.有点难度的是,如何把数字放在上面,让它随着进度条一起动起来。

我们知道,每个View都是个矩形,数字是放在一个矩形TextView中,于是问题就变成了如何让这个矩形围绕着弧形运行,我们先看下面的这张图

如果在你程序设计之时,只考虑到弧形正上方的情况,那么可能会出现如下问题。

a.如果以矩形的底边到弧形距离作为旋转时的参照,那么当矩形旋转到其他方向的时候(非正上、下、左、右),应该如何选取参照?

如果以矩形的某个顶点到弧形距离作为参照,依然很麻烦,需要考虑四个象限中的不同情形,以及矩形旋转到弧形正方向时的特殊情况。

b.如果以矩形中心O1到圆心O距离作为旋转时的参照,那么情况就会好很多,但是我们看弧形右上方的矩形。旋转之后矩形与弧形居然相交了!

聪明的同学从图上可以看出,矩形与圆心距离最近的时候就是矩形的某个顶点旋转到O与矩形中心的连线上的时候。因为在圆内,从圆心出发的线段半径最大嘛。知道这个剩下的事情就好办了,我们只要让大小圆保持相切(圆心距=R+r)即可,当然,距离更大也可以,就是不太好看。

对于TextView来说,我们甚至可以让两个圆稍微相交一点。因为文本不会把TextView填满。字号越大,上下留出的空白就越大。

想知道为什么会有这么大空白的同学,请点这里。另外,Android:includeFontPadding要设置为false!

我们已经知道,让矩形的中心以一定长度围绕圆心旋转即为我们所想要的效果。下面的问题就是如何把这个矩形放到屏幕上面。首先要找出α与矩形中心O2的关系。另外,我们没有办法让android以矩形中心为参照,也就是说,我们要通过α与矩形中心O2的关系找到α与矩形中某个顶点的关系。

我们把圆心距记做D(OO2)。那么

OA = Dcosα,AO2 = Dsinα

圆心O坐标记为(x,y),我们事先是知道弧形的位置的,所以这里的x和y都是已知的。那么O2坐标为

O2(x+Dcosα, y-Dsinα)

至此,α与矩形中心O2的关系我们已经知道了。下面我们计算一下矩形的左上角顶点B(图中没有标出)与α的关系。显然,我们需要知道矩形的宽和高才行。矩形的大小与字号和文字长度有直接关系,这里采取简单粗暴的方法,找个TextView放入你想要的文字和样式,然后截图量一下……宽和高分别记做w和h。那么,B的坐标即为

B(x+Dcosα-w/2, y-Dsinα-h/2)

最后就是一些细节问题了,比如,这里的α变化范围是从210°到-30°。

转贴请保留以下链接

本人blog地址

http://su1216.iteye.com/

http://blog.csdn.net/su1216/

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-31 23:30:18

弧形进度条(动画版)的相关文章

9款极具创意的HTML5/CSS3进度条动画(免积分下载)

尊重原创,原文地址:http://www.cnblogs.com/html5tricks/p/3622918.html 免积分打包下载地址:http://download.csdn.net/detail/yangwei19680827/7352505 今天我们要分享9款极具创意的HTML5/CSS3进度条动画,这些进度条也许可以帮你增强用户交互和提高用户体验,喜欢的朋友就收藏了吧. 1.HTML5/CSS3图片加载进度条 可切换多主题 今天要分享的这款HTML5/CSS3进度条模拟了真实的图片加

【Web前沿技术】纯 CSS3 打造的10个精美加载进度条动画

之前向大家介绍8款优秀的 jQuery 加载动画和进度条插件,今天这篇文章向大家推荐10个纯 CSS3 代码实现精美加载进度条动画效果的方案.加载动画和进度条在网站和 Web 应用中的使用非常流行,特别是在使用 Ajax 技术加载内容的应用场景中,使用时尚的加载动画和进度条告诉用户内容正在加载中是一种非常友好的方式. 您可能感兴趣的相关文章 20个非常绚丽的 CSS3 特性应用演示 23个纯 CSS3 打造的精美LOGO图案 35个让人惊讶的 CSS3 动画效果演示 推荐12个漂亮的 CSS3

9个绚丽多彩的HTML5进度条动画赏析

进度条在网页应用中越来越广泛了,特别是现在的页面异步局部刷新时代,进度条可以让用户更好的等待操作结果.本文要分享9款绚丽多彩的HTML5进度条动画,有很多还是挺实用的,效果也非常不错. 1.CSS3发光进度条动画 超炫酷的样式 这次我们要来分享一款非常炫酷的CSS3进度条动画,其样式风格类似于星球大战里面的那些激光剑效果.页面初始化时,可以设定进度条的值,但是我们也可以利用其配套的借口来动态改变进度条的值,使用起来比较方便.另外以前介绍过一款CSS3 3D进度条,其风格也类似. 在线演示 源码下

详解用CSS3制作圆形滚动进度条动画效果

内  容 先看一下效果图,会提升我们的学习兴趣哟: 对于圆形效果是重点,我将详细讲解. 第一种效果: html结构: <div id="progress"> <span></span> </div> css样式: #progress{ width: 50%; height: 30px; border:1px solid #ccc; border-radius: 15px; margin: 50px 0 0 100px; overflow:

HTML5 canvas带渐变色的圆形进度条动画

query-circle-progress是一款带渐变色的圆形进度条动画特效jQuery插件.该圆形进度条使用的是HTML5 canvas来绘制圆形进度条及其动画效果,进度条使用渐变色来填充,效果非常的酷. 效果演示:http://www.htmleaf.com/Demo/201505271919.html 下载地址:http://www.htmleaf.com/html5/html5-canvas/201505271918.html

JS框架_(JQuery.js)纯css3进度条动画

进度条动画效果: <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="w

iOS实现一个颜色渐变的弧形进度条

在Github上看到一些进度条的功能,都是通过Core Graph来实现.无所谓正确与否,但是开发效率明显就差很多了,而且运行效率还是值得考究的.其实使用苹果提供的Core Animation能够非常简单和方便的实现环形进度条效果,而且还可以高效的保证动画效果,无论是前进还是后退.文字水平比较有限,就多用代码说话. 1.先来一个结果 80%的状态: 99%的状态: 2.需要用到的宏: #define degreesToRadians(x) (M_PI*(x)/180.0) //把角度转换成PI的

【iOS实现一个颜色渐变的弧形进度条】

在Github上看到一些进度条的功能,都是通过Core Graph来实现.无所谓正确与否,但是开发效率明显就差很多了,而且运行效率还是值得考究的.其实使用苹果提供的Core Animation能够非常简单和方便的实现环形进度条效果,而且还可以高效的保证动画效果,无论是前进还是后退.文字水平比较有限,就多用代码说话. 1.先来一个结果 80%的状态: 99%的状态: 2.需要用到的宏: #define degreesToRadians(x) (M_PI*(x)/180.0) //把角度转换成PI的

基于CAShapeLayer和贝塞尔曲线的圆形进度条动画【装载】

初次接触CAShapeLayer和贝塞尔曲线,看了下极客学院的视频.对初学者来说感觉还不错.今天来说一个通过CAShapeLayer和贝塞尔曲线搭配的方法,创建的简单的圆形进度条的教程先简单的介绍下CAShapeLayer1,CAShapeLayer继承自CALayer,可使用CALayer的所有属性2,CAShapeLayer需要和贝塞尔曲线配合使用才有意义.Shape:形状贝塞尔曲线可以为其提供形状,而单独使用CAShapeLayer是没有任何意义的.3,使用CAShapeLayer与贝塞尔