progressbar 颜色_一步一步教你自定义控件—ProgressBar(进度条)

一、前言技术没有先进与落后,只有合适与不合适。本篇的自定义控件是:进度条(ProgressBar)。进度条的实现方式多种多样,主流的方式有:使用多张图片去实现、使用1个或2个Panel放到UserControl上去实现、重载系统进度条去实现等等。本次所实现的进度条仍是使用GDI+去实现。当然,如果只是实现最基本的扁平化的进度条,那完全不需要再写本篇文章,因为直接小改下第一篇的LTrack...
摘要由CSDN通过智能技术生成

一、前言

技术没有先进与落后,只有合适与不合适。

本篇的自定义控件是:进度条(ProgressBar)。

进度条的实现方式多种多样,主流的方式有:使用多张图片去实现、使用1个或2个Panel放到UserControl上去实现、重载系统进度条去实现等等。

本次所实现的进度条仍是使用GDI+去实现。当然,如果只是实现最基本的扁平化的进度条,那完全不需要再写本篇文章,因为直接小改下第一篇的LTrackBar就行了。

既然写这篇文章,就是实现不一样的、比较好玩和好看的进度条,如环形进度条、饼形进度条等等。

本篇使用的知识都是前几篇中已经讲过的,并没有新的技术。但是却附加了一些想像力,一些不拘一格、稍稍突破常规的想像力。


二、前期分析

(一)为什么需要自定义进度条?

系统自带的滚动条样式太过单调,同时不够“扁平化”,所以便去实现自己的滚动条。

3bbb3542a29a8d3d15429deb093fd718.png

(二)实现目标

1,支持三种样式

(1)横条(Bar)

 f414e3607fba8ceedeeed6ef88c1fca8.png

(2)圆饼(Pie)

 c047f515c7a67b81785dec55d4815fc8.png

(3)圆弧(Arc)

 ddb638e75ec1076483c2b2d201fa477d.png

2,支持显示和隐藏百分比

(1)横条(Bar)

 7d186f03bd24905a1d04347473149b8b.png

(2)圆饼(Pie)

 a06f40916b5aaab7636ac1fb8e7d6493.png

(3)圆弧(Arc)

 974c1e8ee175e1be2e5bcf381888b18c.png

3,支持多种进度形状

(1)连续

 93e986b71b1f5ff332fd3adc448948ef.png

(2)分段块

 835b5f392e5204e593caefb06b6c325a.png

(3)两段式:先分段块再连续

 aebb6986d959bce4ed8d6002934122a1.png

(4)螺旋

(注:只有“横条”样式时才支持螺旋形状)

 f6f241b3562837a76430c79a27aa0857.png

4,支持Marquee样式

当进度无法确定时,便需要使用Marquee样式,同系统进度条的“Marquee”样式类似。

不过支持更多的Marquee样式。

(1)左右摆动

 dff1327b6bacb1fc99fe8cc37cedd279.gif

(2)循环穿过

 c3427a492ec53a0917a9e1f85ccedd63.gif

(3)往复(连续)

 99b9e33a114de24480398ce7773b1e44.gif

(4)划过(连续)

 fe9c514e4aefe298b79e99fd83b95e44.gif

(5)往复(分段块)

 f445634345e3bb4df76defe6d001482a.gif

(6)划过(分段块)

 2ea391b6c907c25ffe687cc75f64a0fa.gif

(7)螺旋

 fae284aa5331d7ed984b0b5f3555d2ab.gif

5,支持调整进度条各元素尺寸和颜色

(1)设置边框厚度和颜色

 b875443e0b23893398197513a811e43b.gif

(2)设置背景大小和颜色

 e59c3b1cc541a8198cc727a7147dabeb.gif

(3)设置进度绘制位置和颜色

 d76919f087df64634477e70bbf17e621.gif

(4)设置进度文本颜色

 e2e22fa0ea758f8e42466e87ae0eede3.gif

(5)设置弧线厚度(仅样式为“圆弧(Arc)”时有效)

 eb931ccd51a0948684ac3cda6366368c.gif

(6)设置“分段块”厚度(仅进度条形状为“分段块”时有效)

 18f16a302ad3db1dae022946194101e4.gif


三、进度条拆解

看了上面的实现目标,是不是感觉眼花缭乱、无从下手?

下面我就对进度条进行拆分讲解,一步一步来看上面的效果是怎么实现的。

(一)组成元素

进度条由三个部分组成,分别是:进度边框、背景

下面是各种样式下,三个组成部分的拆分。

1,横条(Bar)

 8ff96255bb3352213b0c44ec8337a564.png

2,圆饼(Pie)

 ac5bd063e0545bf861004c4dfaccf145.png

3,圆弧(Arc)

 6b339580882844093e75e8fb14e93f9d.png

(二)元素属性

进度条的三个组成元素,都有着各自相关的属性。

(注:因为“颜色”属性是必备的,所以不再赘述。)

1,边框

其相关属性为:边框的厚度

当“厚度”为0时,看起来进度条就没有边框;

当“厚度”超过控件高度的二分之一时,整个进度条就变成了边框的颜色。

(注:因为是先绘制“背景”,再绘制“边框”,所以是“整个进度条变成边框的颜色”)

A,对于 “橫条(Bar)”,其边框厚度如下图所示:

38b1ff14c9bec749d673167c6d93374a.png

B,对于“圆饼(Pie)”、“圆弧(Arc)”,其边框厚度如下图所示:

230a13bb7afdb7bda7907c6c68e6df4d.png

2,背景

其相关属性为:背景的大小

背景的大小就是背景绘制的范围,这里用一个自造词“收缩宽度”来进行描述。

当“收缩宽度”为0时,背景大小=控件本身大小;

当“收缩宽度”为x时,背景宽度=控件宽度-2*x,背景高度=控件高度-2*x;

当“收缩宽度”超过控件高度的二分之一时,背景高度=控件高度-2*(控件高度/2)=0,此时进度条将没有了背景。

A,对于 “橫条(Bar)”,其收缩宽度如下图所示:

f361d3a2dcbba67ee741f55bbdd079b5.png

B,对于“圆饼(Pie)”、“圆弧(Arc)”,其收缩宽度如下图所示:

af43233cb801819f40bc0f102e93f71f.png

3,进度

其相关属性有:进度绘制范围、进度样式

A,进度绘制范围

顾名思义,就是进度可绘制的范围,这里用“绘制边框距离”来进行描述。

当“绘制边框距离”为0时,进度的绘制范围=控件本身大小;

当“绘制边框距离”为x时,进度的绘制起点:(x,x),绘制终点:(控件宽度-x,控件高度-x),所以绘制范围=(控件宽度-2*x,控件高度-2*x);

当“绘制边框距离”超过控件高度的二分之一时,进度的绘制高度将为0,也代表着没有进度。

A,对于 “橫条(Bar)”,其绘制边框距离如下图所示:

18a9ce9bcce4c71a9e954d93bf39b715.png

B,对于“圆饼(Pie)”,其绘制边框距离如下图所示:

2423b45db81c5509c9880a5a5747a63d.png

C,对于“圆弧(Arc)”,其绘制边框距离如下图所示:

ccc1335be7c32201e109cef0d41a0ef3.png

B,进度样式

进度样式就是前节实现目标中各种进度的样式,有连续的、有分段块的、有螺旋的等等。

这此样式大部分一看都知道如何实现的。

比如“连续”,在“橫条(Bar)”样式中,就是填充一个矩形;在“圆饼(Pie)”中,就是填充一个扇形;在“圆弧(Arc)”中,就是画一段弧线。

比如“分段块”,在“橫条(Bar)”样式中,就是等间隔填充多个矩形;在“圆饼(Pie)”中,就是等间隔填充一个扇形;在“圆弧(Arc)”中,就是等间隔画一段弧线。

在这里,我将详细讲解一个特殊的形状:“螺旋”,因为“螺旋”样式除了不太能直观想像出来之外,还有不少细节需要处理。

因为只有“橫条(Bar)”样式进度条有“螺旋”样式,所以接下来的讲解都是以“橫条(Bar)”为基础进行讲解的。

同时,为了避免干扰,前面的两个属性“边框”和“背景”都将保持默认值,即:没有边框,背景大小=控件大小。“进度绘制范围”也是默认值,即绘制范围=控件大小。

(1)“螺旋”样式实现讲解

A,进度明确时

即进度是已知且确定的,比如5%,33%等等。其外观样式如下:

 ca43ddeaca483c48a1da1dd0deba315a.png

其示意图如下:

 e80aaebf88eb9f7a19694def14c95394.png

其中蓝色的平行四边形就是“螺旋”,其本身是一个背景透明、上有多个蓝色平行四边形的图片。

进度的增减实质上就是这个图片在控件上的左右移动。

那么,这个图片要和控件大小相等,特别是宽度相等。但是在使用GDI+去生成这个图片时,却不能让图片宽度与控件宽度相等。

我们在往图片绘制平行四边行时,是从右往左依次绘制的,之所以从右侧开始绘制,是为了保证进度条的右侧样式是固定的,固定在一个比较美观的状态。因为在进度变化时,即图片左右移动时,我们目光的焦点是在右侧,所以一个固定的右侧样式就比较重要,否则当控件宽度变化时,右侧的样式就随之变化。

当图片宽度与控件宽度相等时,会出现下面这种情况,即进度条的最右侧下方有空白。如下图所示:

 (其中上面图形是实际绘制图片,下面图形是将图片截取,和进度条宽度相等后样式)

3bc2f25063d061612b16d8d4f03c040d.png

所以我们令图片的宽度=控件的宽度+1个平行四边行的宽度。在绘制完图片后,我们从中截取出一个和控件宽度一样的图片,这样,整体的样式就比较好看。如下图所示:
 (其中上面图形是实际绘制图片,下面图形是将图片截取,和进度条宽度相等后样式)

2313a9712dad66d1af087536dd299ad3.png 

综上,就是按照下图所示的5步依次实现:

 9a66a21cc8cc09c30413a018d4626150.png

B,进度未知时

即进度是不确定的,就像系统进度条的Marquee样式那样。其外观样式如下:

 fae284aa5331d7ed984b0b5f3555d2ab.gif

同上,上方仍是一个背景透明、上有多个蓝色平行四边形的图片。上图的效果就是这个图片在不段的循环移动。

具体示意如下,图片不断向右侧移动,当右侧超过一个平等四边行时,图片恢复原位,然后不断循环。

 4198dced50cebfaa9d96c5c00280a811.png

通过上方的示意图,我们发现一个特点,就是图片的宽度不再等于(控件的宽度+1个平行四边行的宽度),而是等于(控件的宽度+2个平行四边行的宽度)。原因如下:

在画示意图时,为了方便直观查看,平行四边形正好是两个相对的直角三角行,而实际绘制时,很少会有这种样式,大多都是两个相对的钝角三角行组成的平等四边形的样子,如下图所示:

 a65e0e00bcb434563a33c903272e65d3.png

这种情况下,如果图片的宽度=控件的宽度+1个平行四边行的宽度,那么在移动到最右侧时和复位时都会出现额外的空白,如下图所示:

 57466b469806cbe5d5490b7e5519d4ee.png

所以,才会令:图片的宽度=控件的宽度+2个平行四边行的宽度。

(三)其它属性

除了前面的与进度条元素直接相关的属性外,还有一些其他属性,这些属性都是在某种特定样式下才起有作用。

1,弧线宽度

在“圆弧(Arc)”样式的进度条中,“进度”就是一段圆弧,所以在其他属性外,还要有“弧线本身宽度”这样一个属性。

在默认情况下,弧线宽度=控件宽度/10,因为当进度达到100%时,弧线就变成了圆环,此时看起来有弧线的地方占控件宽度的五分之一,是一个比较常规的宽度。

通过调用弧线宽度,可以实现一些特殊的效果。

6a38242469b98cc5f0ff108f659130d4.png 

2,分段

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于 Android 自定义进度条控件的实现,我可以为您提供一些思路和示例代码。 首先,我们需要继承自 View 或者 ProgressBar,然后在 onDraw 方法中实现自己的绘制逻辑。具体来说,需要绘制背景、进度条和文本等内容。 示例代码如下: ```java public class CustomProgressBar extends ProgressBar { private Paint mPaint; private String mText; private Rect mRect; public CustomProgressBar(Context context) { super(context); init(); } public CustomProgressBar(Context context, AttributeSet attrs) { super(context, attrs); init(); } public CustomProgressBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { mPaint = new Paint(); mPaint.setAntiAlias(true); mRect = new Rect(); } @Override protected synchronized void onDraw(Canvas canvas) { super.onDraw(canvas); // 绘制背景 mPaint.setColor(Color.GRAY); mPaint.setStyle(Paint.Style.FILL); canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint); // 绘制进度条 mPaint.setColor(Color.BLUE); mPaint.setStyle(Paint.Style.FILL); float progress = getProgress() * 1.0f / getMax(); canvas.drawRect(0, 0, getWidth() * progress, getHeight(), mPaint); // 绘制文本 mPaint.setColor(Color.WHITE); mPaint.setTextSize(24); mText = getProgress() + "%"; mPaint.getTextBounds(mText, 0, mText.length(), mRect); float x = getWidth() / 2f - mRect.centerX(); float y = getHeight() / 2f - mRect.centerY(); canvas.drawText(mText, x, y, mPaint); } } ``` 这个自定义控件实现了一个简单的水平进度条,包括了背景、进度条和文本三个部分。当然,您可以根据自己的需求进行更改和扩展。 希望这个示例代码能够帮助到您,如果您还有其他问题,欢迎继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值