本博客只要没有注明“转”,那么均为原创,转贴请注明本博客链接链接
我们先把问题分解为下面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地址
相关推荐
标题提到的“android 弧形进度条”是指一种非线性的进度指示器,它以弧形的形式展示进度,区别于常见的线性进度条(Progressbar)和滑动条(Seekbar)。这种弧形进度条通常用于显示任务或操作的完成度,例如加载、...
本文将深入探讨`SemicircleProgress`库,它为开发者提供了两种独特的进度显示方式:弧形进度条和圆形扩散进度条。这两种控件能够为应用程序增添视觉吸引力,同时有效地传达加载、等待或进度更新的状态。 首先,我们...
在进度条动画中,可能使用了变换来让进度条在填充过程中有特定的形状变化,比如波浪形、弧形等,增加视觉趣味性。 4. **其他CSS3属性**:除了上述的特性,还可以利用其他CSS3属性,如阴影(box-shadow)、渐变...
FFmpegDemo-master.zip是一个包含使用FFmpeg库进行视频压缩,并且具有自定义进度条动画功能的Android项目。这个项目不仅提供了基本的视频压缩服务,还允许开发者和用户自定义进度条样式,添加动画效果,以及实现...
圆形进度条通常由一个圆形背景和填充的弧形路径组成,填充的弧度代表了当前的进度。它能够直观地展示出进度的百分比,随着任务的完成,填充的弧度会逐渐增加。这种设计在移动应用、加载动画、数据可视化等领域有着...
创建一个`GraphicsPath`对象,然后使用`AddArc`方法添加一个弧形,参数包括圆心坐标、半径和起始/结束角度,以此来表示进度条的轮廓。 5. **渐变刷和填充**:为了使进度条看起来更美观,我们可以使用`...
对于圆形进度条,可以使用Paint的arcTo方法画出弧形,并根据进度改变弧形的角度;对于长形进度条,可以通过改变Rect的位置和大小来模拟进度的移动。此外,还可以通过ColorFilter或者Shader来实现进度条的颜色渐变,...
2. **颜色和动画效果**:自定义进度条可以自由设定填充颜色、边框颜色、背景颜色,甚至支持渐变色和动态变化效果,如平滑过渡、闪烁等,使进度反馈更生动。 3. **多态性**:原生控件可能仅支持单方向的进度指示,...
在这个过程中,你会使用到`Canvas`对象来绘制图形,例如使用`drawCircle()`绘制圆,`drawArc()`绘制弧形,以及`drawText()`添加文字。 2. **属性动画**: 为了实现进度的动态更新,可以利用Android的属性动画系统。`...
5. **动画效果**:为了提升用户体验,我们可以添加动画效果,使进度条平滑过渡。这可能涉及到`ObjectAnimator`或`ValueAnimator`,通过它们可以随着时间线性地改变进度值。 6. **兼容性问题**:考虑到Android平台的...
总结来说,这个自定义控件提供了在Android中创建圆弧形进度条并显示百分比的示例,对于希望深入理解Android自定义视图机制和提升界面设计能力的开发者来说,是一份有价值的参考资料。通过学习和实践,开发者可以...
2. **弧形进度条**:一种非标准的线性形状,可能通过自定义ViewGroup和绘图代码来实现,使进度条呈现弧形路径。 3. **圆形进度条**:除了原生的圆形进度条,源码可能还提供了带有填充色或者渐变色的自定义版本,或者...
同时,进度条支持动画效果,使得进度变化更自然流畅。 5. **API简介**: JhDownProgressView提供了简洁易懂的API接口。如`setProgress(progress:)`用于设置进度,`setFinishStatus(isFinish:)`用于设置完成状态,`...
例如,通过`ValueAnimator.ofFloat()`创建一个动画,改变`Progress`属性,然后在`AnimatorUpdateListener`中更新进度条的值,调用`invalidate()`使控件重绘。 4. **属性定制**: 为了让自定义圆形进度条易于配置,...
在这个圆形进度条中,`Canvas.drawArc()`方法可能会被用来画出弧形进度。 3. **属性动画**: 为了让进度条动起来,Android提供了属性动画系统,可以平滑地改变一个对象的属性值。`ObjectAnimator`或`ValueAnimator...
6. **属性动画**:在Android 3.0及以上版本,可以使用属性动画API来实现更复杂的动画效果,比如改变进度条颜色、速度等。 7. **数据绑定**:为了将数据(如进度值)与视图绑定,开发者可能会使用Android Data ...
这可能包括改变进度条的形状(如矩形、圆形或弧形),以及选择不同的颜色方案来代表不同状态(如已完成、正在进行、未开始)。 2. **百分比显示**:在自定义进度条中添加百分比是增强用户体验的一个关键特性。它...
加载中(Loading)或Progress Progress则是进度条的一种特殊形式,常常以动画的形式呈现,给予用户操作正在后台执行的视觉反馈。本资源“安卓进度条loadingprogress相关-android实现图表环形进度条.rar”似乎包含了...
进阶功能包括:多图表区域、数据绑定、动画效果、自定义绘图等。例如,通过添加新的`ChartArea`,可以在同一窗口显示多个图表;通过`Series.IsValueShownAsLabel`可以显示数据点的值;`Series.MarkerStyle`可以设置...
环形进度条是一种常见的UI元素,它以图形化的方式显示任务或数据的完成进度,通常呈圆形或弧形分布。在软件开发中,特别是在移动应用和网页设计中,环形进度条的应用非常广泛,用于展示下载进度、加载状态或者健康...