Android自定义ProgressBar

57 篇文章 13 订阅
订阅专栏

        好久不写博客了,今天来总结一下自定义ProgressBar的实现。上周做一个游戏资源的在线更新功能,设计给的加载进度条设计图,是无法使用Android原生的ProgressBar来实现的。在百度和GitHub上搜了搜相关的资源,都不符合我的要求。于是,我只能自己去写。先给一下最终的效果:

        上面就是我实现的ProgressBar的效果,与业务结合起来,分为几个阶段:

(1)检查配置阶段:检查本地现有的资源和服务器的配置,确定是否存在新的资源需要下载。

(2)下载阶段:如果存在新的资源,开始下载新的资源。

(3)解压缩阶段:下载完成新资源后,开始解压缩资源包。

一.撸代码前的思考

        刚工作的时候,做的项目或者功能都有很长的开发周期。我们会在开发前充分的去做需求分析和设计,讨论技术难点和可能遇到的一些坑。而且,由于开发周期长,允许我们在开发的过程中犯一些错误。不过,现在的工作,根本不会给我推倒重来的时间。所以,逐渐的,我养成了习惯,那就是在写代码之前先想一想如何去实现:

(1)我需要画一个进度条,这个进度条至少包括已达到的进度和未达到的进度

(2)这个进度条需要和更新进度联动,需要包括一个展示更新阶段的文本

(3)这个进度条需要一个用于告知用户百分比的文本

(4)这个进度条需要一个小滑块,来使我们的进度条更美观

二.开始撸代码

        我们可以把这个进度条看做两个主要部分:已经达到的进度和未达到的进度,还有进度文本和百分比展示,最后是一个滑块。而且,这个进度条是个圆角的矩形(只只不过长度远远大于高度)。所以,我们的思路是,画两个圆角矩形。那么,我们该如何确定我们进度条的各个元素从什么地方开始画,画到哪个位置结束呢?这就需要我们简单的计算一下。

1.计算未达到进度的位置,这里其实就是进度条的背景

        mUnreachedRectF.left = getPaddingLeft();
        mUnreachedRectF.top = (getHeight() - mBarHeight) / 2.0f;
        mUnreachedRectF.right = getWidth() - getPaddingRight();
        mUnreachedRectF.bottom = (getHeight() + mBarHeight) / 2.0f;

(1)left是矩形的最左边,就是我们画布的最左边,其实就是0。但是为了美观,我们不可能从画布的最左边开始画的,我们可能会设置一个padding,所以,我们使用的初始x坐标为:paddingLeft

(2)top是我们矩形的最上面,我们取的坐标是(画布的高度-进度条的高度)/2。

(3)right是矩形的最右边,取的坐标是:画布的宽度减去右边的padding。

(4)bottom是矩形的底部,这里可以对照top的计算,其实目的就是要让我们的矩形处于画布的中间。因此,以画布高度的中间为参考点,top就是画布高度的一半减去进度条高度的一半,而bottom则是画布高度的一半加上进度条高度的一半:

2.计算已达到的进度条的位置

        mReachedRectF.left = getPaddingLeft() + dp2px(2);
        mReachedRectF.top = (getHeight() - mBarHeight) / 2.0f + dp2px(2);
        mReachedRectF.right = (getWidth() - getPaddingLeft() - getPaddingRight()) / 
        (getMax() * 1.0f) * getProgress() + getPaddingLeft();
        mReachedRectF.bottom = (getHeight() + mBarHeight) / 2.0f - dp2px(2);

(1)left:比起背景,我们更往右了2dp,因为我们的已达到进度会比背景小一些,以实现嵌套的效果

(2)top:也是一样,比背景更往下2dp

(3)right:这个虽然很长,其实就是进度条背景的长度去乘上当前的进度(例如当前的进度是80%,那其实就是背景的长度*80%),后面加上paddingleft,其实,还应该加上2dp,不过,我们可以忽略不计。

(4)bottom:比背景往上2dp

3.计算两个文本区域的位置

(1)比起画矩形我们需要告诉canvas我们的上下左右位置,画文本我们只需要告诉canvas最左边和最上边,下面是百分比的显示位置:

canvas.drawText(mCurrentDrawText, mUnreachedRectF.right - dp2px(36), getHeight() / 2 + 2 * mBarHeight, mPaint);

        最左边,就是矩形的最右边减去一个值,这个值就是我们百分比这几个数字的大体宽度。最上边,就是画布高度的一半再加上一块高度,在这里我取了两倍的进度条高度。这样就可以让进度条百分比最右侧与进度条终点大致对齐,让其位于进度条下方。

 (2)下面是显示更新阶段的文本的位置计算:

canvas.drawText(mHint, mReachedRectF.left, getHeight() / 2 + 2 * mBarHeight, mPaint);

        最左边的位置,就是矩形的最左边,最上边,跟百分比的最上面一样,不再赘述。

4.计算滑块的位置

        最后,是计算滑块的位置,其实它的位置也比较好计算。然后我们调用canvas.drawBitmap即可:

mSliderLeft = (getWidth() - getPaddingLeft() - getPaddingRight()) / (getMax() * 1.0f) * getProgress() + getPaddingLeft() - mSliderWidth / 2;
mSliderTop = (getHeight() - mSliderHeight) / 2.0f;
canvas.drawBitmap(mSlider, mSliderLeft, mSliderTop, mPaint);

left:其实就是已达成进度的最右边减去滑块宽度的一半,也就是让滑块的中间与已达成进度大致重合。

top:与进度条的top一样的计算。为了美观,我们会让滑块的位置稍微超出进度条顶部一点点。

5.绘制

(1)绘制进度条背景(未达成进度):

private void drawUnReachedRectF(Canvas canvas) {
        mPaint.setShader(null);
        mPaint.setColor(mUnreachedBarColor);
        canvas.drawRoundRect(mUnreachedRectF, mRadius, mRadius, mPaint);
    }

(2)绘制进度条已达到部分:

private void drawReachedRectF(Canvas canvas) {
        mLinearGradient = new LinearGradient(0, 0, mReachedRectF.right,
                0,
                startColor,
                endColor,
                Shader.TileMode.CLAMP);
        mPaint.setShader(mLinearGradient);
        canvas.drawRoundRect(mReachedRectF, mRadius, mRadius, mPaint);
    }

 (3)绘制进度条进度:

    private void drawProgress(Canvas canvas) {
        mPaint.setShader(null);
        mPaint.setColor(mTextColor);
        mPaint.setTextSize(dp2px(20f));
        String mCurrentDrawText = new DecimalFormat("#").format(getProgress() * 100 / getMax());
        mCurrentDrawText = mCurrentDrawText + "%";
        canvas.drawText(mCurrentDrawText, mUnreachedRectF.right - dp2px(36), getHeight() / 2 + 2 * mBarHeight, mPaint);
    }

(4)绘制进度条文本:

    private void drawHint(Canvas canvas) {
        mPaint.setShader(null);
        mPaint.setColor(mTextColor);
        mPaint.setTextSize(dp2px(12f));
        if (mProgress <= 20) {
            mHint = "正在检查配置...";
        } else if (mProgress > 20 && mProgress <= 60) {
            mHint = "正在下载资源...";
        } else {
            mHint = "正在解压,本过程不消耗流量...";
        }
        canvas.drawText(mHint, mReachedRectF.left, getHeight() / 2 + 2 * mBarHeight, mPaint);
    }

(5)绘制滑块:

    private void drawSlider(Canvas canvas) {
        mPaint.setShader(null);
        mPaint.setColor(Color.WHITE);
        canvas.drawBitmap(mSlider, mSliderLeft, mSliderTop, mPaint);
    }

三.其他注意事项

1.滑块bitmap的获取

使用BitmapFactory获取bitmap,然后创建指定大小的滑块:

mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.idiom_load_cloud);
mSlider = Bitmap.createScaledBitmap(mBitmap, (int) dp2px(26), (int) dp2px(16), true);

2.bitmap的回收

为了防止内存泄漏,需要在合适的时机销毁bitmap:

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (mBitmap != null && !mBitmap.isRecycled()) {
            mBitmap.recycle();
            mBitmap = null;
        }
        if (mSlider != null && !mSlider.isRecycled()) {
            mSlider.recycle();
            mSlider = null;
        }
    }

        以上就是对自定义进度条的实现。掌握关键的方法后,我们可以根据自己的需求,轻松的自定义进度条。下一篇博客,将会介绍几种让进度条动起来的方式。

自定义圆形的ProgressBar
无为
02-28 1329
1.自定义圆形的ProgressBar   效果图:   圆形ProgressBar的样式主要有以下几个,我们这里以progressBarStyleLarge为例进行样式的修改,其他的类似。       ProgressBar  android:layout_width="wrap_content"   android:layout_height="wrap_conten
Android 自定义ProgressBar
WangShuo的专栏
10-31 832
效果如图调用代码如下package com.example.MyProgressbar;import com.ws.progressView.HorizontalProgress; import com.ws.progressView.RoundProgress;import android.app.Activity; import android.app.ActionBar; import and
Android开发自定义实现炫酷的进度条
qq_36451275的博客
11-08 851
Android开发自定义实现炫酷的进度条
Android ProgressBar颜色设置
最新发布
weixin_40771797的博客
08-12 162
Android ProgressBar 颜色设置指南 在 Android 开发中,ProgressBar 是用于显示进度的常用组件。在这篇文章中,我们将学习如何自定义 ProgressBar 的颜色。我们将按照以下步骤进行操作: 步骤 描述 步骤 1 创建一个新的 Android 项目 步骤 2 在布局中...
Android基础--自定义ProgressBar
star_nwe的博客
05-07 1386
ProgressBar为进度条控件,有Indeterminate不确定模式和Determinate确定模式两种:①不确定模式通常使用圆形循环动画来表示类似“正在加载”的过程,进度无法确定,具有不确定性;②确定模式是通过将已发生的进度与总量的百分比显示在进度条上,比如下载或上传文件的数量等。
android自定义progressbar 图片,自定义ProgressBar(自定义View和ClipDrawable)
weixin_29366307的博客
05-25 956
开发中经常需要自定义ProgressBar,这里用了自定义View和ClipDrawable实现简单的ProgressBar自定义View效果:public class CustomProgressBar extends View {private Paint mBgtPaint;//底部背景画笔private Paint mProgressPaint;//progress画笔private in...
Android自定义Progressbar
04-16
总之,Android自定义Progressbar是一项重要的UI定制技术,通过结合ProgressDrawable、动画和自定义代码,我们可以创造出各种独特的进度指示器,满足不同设计需求,提升用户体验。在实际项目中,根据应用场景选择合适...
android 自定义ProgressBar
04-23
本文将深入探讨如何在Android自定义ProgressBar,以满足各种设计需求和提升用户界面的美观度。 首先,我们了解下Android原生的ProgressBar。原生的ProgressBar有两种类型:Horizontal(水平)和Circular(圆形)...
android 自定义progressbar
08-13
自定义ProgressBar则可以满足开发者对于界面个性化的需求,让应用的UI更加独特和吸引人。本篇将详细讲解如何实现一个自定义ProgressBar,并结合给定的"TestCustomProgressBar"文件进行说明。 首先,我们来了解...
android自定义progressbar组件
01-04
使用android逐帧动画实现自定义loading进度条
多种风格的Android 自定义progressbar控件
07-03
本项目"多种风格的Android自定义progressbar控件"提供了多种不同设计风格的进度条,让开发者可以根据自己的应用主题和需求选择合适的样式。 首先,我们来看看自定义ProgressBar的基本概念。在Android中,可以通过...
Android自定义ProgressBar
冰点蓝欣的专栏
02-26 2144
本文简单介绍下Android自定义ProgressBar。
Android ProgressBar自定义图片进度,自定义渐变色进度条
strliu的专栏
05-30 2458
↳    android.view.View 3        ↳    android.widget.ProgressBar 4 直接子类 5 AbsSeekBar 6 间接子类
Android 自定义progressbar
FlyPig_Vip的博客
05-27 311
<ProgressBar android:id="@+id/otherProgress" style="?android:attr/progressBarStyleHorizontal" android:layout_width="@dimen/x40" android:layout_height="match_parent" android:layout_below="@id/l.
Android ProgressBar自定义图片进度,自定义渐变色进度条
weixin_34198762的博客
05-28 312
为什么80%的码农都做不了架构师?>>> ...
Android自定义进度条
Small_Lee的博客
08-03 861
效果图代码实现首先讲一下自定义View的一个大致的步骤有哪些: 自定义属性的声明与获取 测量onMeasure 布局onLayout(ViewGroup) 绘制onDraw onTouchEvent onInterceptTouchEvent(ViewGroup)实现上图所示的效果,我们只需要用到1,2,4这三个步骤,接下来就带大家一步步实现。 自定义属性的声明与获取首先,在当前项目的values文
Android自定义ProgressBar:炫酷横向&环形进度条实战
我们将探讨如何改变系统默认的ProgressBar外观,同时保持其稳定性和特性,实现自定义进度条效果。" 在Android开发中,系统自带的ProgressBar虽然功能强大,但样式可能无法满足所有设计需求。为了追求更加个性化和...
写文章

热门文章

  • Android逆向(一)Android逆向工具(一) 39624
  • Kotlin学习(一)IntelliJ IDEA搭建Kotlin开发环境 33282
  • Android逆向(三)修改资源文件 30428
  • 【干货】解决AndroidStudio报错Cause: unable to find valid certification path to requested target 30204
  • Java五种单例模式 29168

分类专栏

  • 鸿蒙 9篇
  • 数据结构 3篇
  • IDEA 3篇
  • SpringBoot 10篇
  • python 13篇
  • Unity3D 3篇
  • Android 57篇
  • Android三方框架 13篇
  • 反编译 7篇
  • Java 3篇
  • Kotlin 2篇

最新评论

  • Android最火的框架系列(七)Retrofit

    zgw..: Retrofit2怎么结合 MVVM 框架使用,现在能找到的都是kotlin版本的。

  • 如何卸载Android自带系统应用

    我的世界Edge: well

  • 如何卸载Android自带系统应用

    MUZHOUT86: 啊,真的吗,我正想卸应用商店

  • SpringBoot(九)jwt + 拦截器实现token验证

    虚妄狼: 泰裤辣!

  • SpringBoot(九)jwt + 拦截器实现token验证

    普通网友: 写的很好!我也写了一篇获取【大厂面试真题解析、核心开发学习笔记、最新全套讲解视频、实战项目源码讲义、学习路线简历模板】的文章

大家在看

  • python函数二:局部变量、全局变量、位置参数、关键字参数、缺省参数、不定长参数 1100
  • Springboot基于SpringBoot的在线考试系统e422o程序+源码+数据库+调试部署+开发环境
  • 小时候看的多啦A梦中的哪些是与人工智能相关的道具,现在已经实现了
  • C++ asio异步网络库学习记录
  • 论哈希是什么 1968

最新文章

  • 鸿蒙开发(九)UI实战 - 线性布局实现登录界面
  • 鸿蒙开发(八)添加常用控件(下)
  • 鸿蒙开发(七)添加常用控件(上)
2024年7篇
2023年25篇
2022年21篇
2021年2篇
2020年21篇
2019年42篇
2018年3篇
2015年3篇

目录

目录

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个玩游戏的程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或 充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值

玻璃钢生产厂家艺术玻璃钢雕塑工艺文山玻璃钢仿真雕塑淮北定制玻璃钢雕塑多少钱深圳高品质商场美陈宁夏玻璃钢雕塑制作厂家宿州多彩玻璃钢雕塑哪家便宜景区玻璃钢雕塑销售电话许昌广场玻璃钢雕塑价格玻璃钢大型雕塑定制昆明玻璃钢雕塑联系方式宋庄玻璃钢雕塑厂福建商场主题创意商业美陈博尔塔拉动物玻璃钢雕塑设计玻璃钢小羊动物雕塑厂家陕西多彩玻璃钢雕塑优势湖北观音玻璃钢佛像雕塑临沂玻璃钢雕塑联系方式保定玻璃钢佛像雕塑济南动物玻璃钢雕塑安装辽宁玻璃钢雕塑厂家直销玻璃钢雕塑超级飞侠座椅雕塑玻璃钢能做什么效果重庆有没有做玻璃钢雕塑的安徽省玻璃钢雕塑怎么选雕塑不锈钢和玻璃钢云南玻璃钢马雕塑价格玻璃钢树脂雕塑大门韶关仿真玻璃钢卡通雕塑玻璃钢雕塑喷漆图片武义人物玻璃钢雕塑工艺香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化