Android 绘制圆形进度条

Android 绘制圆形进度条

最近项目上有一些需求,需要绘制圆形的进度条满足设计上和交互上的需求:
效果图

实现思路

在画布上直接绘制View,需要了解一下几点
1.需要画一个圆
2.圆圈上有不同进度的颜色
3.圆圈中有进度数字的展示
4.圆圈中间还有可以自定义不同文案提示

一、画圆

需要使用Canvas的该方法

 public void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter,@NonNull Paint paint) {drawArc(oval.left, oval.top, oval.right, oval.bottom, startAngle, sweepAngle, useCenter,paint);}

如下:

 // 设置画笔相关属性mPaint.setAntiAlias(true);mPaint.setColor(Color.rgb(0xe9, 0xe9, 0xe9));canvas.drawColor(Color.TRANSPARENT);mPaint.setStrokeWidth(mCircleLineStrokeWidth);mPaint.setStyle(Style.STROKE);// 位置mRectF.left = mCircleLineStrokeWidth / 2; // 左上角xmRectF.top = mCircleLineStrokeWidth / 2; // 左上角ymRectF.right = width - mCircleLineStrokeWidth / 2; // 左下角xmRectF.bottom = height - mCircleLineStrokeWidth / 2; // 右下角y// 绘制圆圈,进度条背景canvas.drawArc(mRectF, -90, 360, false, mPaint);

此时画出了默认的背景圆圈:
画背景圆圈

二、画进度圆弧

其实实现很简单,换另外一种颜色同样在画布上画出即可,支持此时画的不是360°,而是通过进度计算出来的一个圆弧。

mPaint.setColor(Color.rgb(0xf8, 0x60, 0x30));
canvas.drawArc(mRectF, -90, ((float) mProgress / mMaxProgress) * 360, false, mPaint);

如上即可,此时mProgress / mMaxProgress = 80/100;即可绘制出如下效果
进度效果图

三、画中间进度百分比

其实要用到Canvas中绘制文本的方法:

public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) {native_drawText(mNativeCanvasWrapper, text, 0, text.length(), x, y, paint.mBidiFlags,paint.mNativePaint, paint.mNativeTypeface);
}

如下:

// 绘制进度文案显示
mPaint.setStrokeWidth(mTxtStrokeWidth);
String text = mProgress + "%";
int textHeight = height / 4;
mPaint.setTextSize(textHeight);
int textWidth = (int) mPaint.measureText(text, 0, text.length());
mPaint.setStyle(Style.FILL);
canvas.drawText(text, width / 2 - textWidth / 2, height / 2 + textHeight / 2, mPaint);

主要要计算好画的位置,drawText中对应就是相关的位置,相当于居中显示进度百分比文案。效果如下:
百分比居中显示

四、画圆圈中间提示文案

方法同三,只不过要计算出画的位置即可,效果图如下:
中间文案显示

五、总结

其实很多自定义的View都可以用Canvas直接画出来,如果项目上有类似这样的需求,可以先研究Canvas的使用和原理。
最后附上源码:

public class CircleProgressView extends View {private static final String TAG = "CircleProgressBar";private int mMaxProgress = 100;private int mProgress = 30;private final int mCircleLineStrokeWidth = 8;private final int mTxtStrokeWidth = 2;// 画圆所在的距形区域private final RectF mRectF;private final Paint mPaint;private final Context mContext;private String mTxtHint1;private String mTxtHint2;public CircleProgressView(Context context, AttributeSet attrs) {super(context, attrs);mContext = context;mRectF = new RectF();mPaint = new Paint();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);int width = this.getWidth();int height = this.getHeight();if (width != height) {int min = Math.min(width, height);width = min;height = min;}// 设置画笔相关属性mPaint.setAntiAlias(true);mPaint.setColor(Color.rgb(0xe9, 0xe9, 0xe9));canvas.drawColor(Color.TRANSPARENT);mPaint.setStrokeWidth(mCircleLineStrokeWidth);mPaint.setStyle(Style.STROKE);// 位置mRectF.left = mCircleLineStrokeWidth / 2; // 左上角xmRectF.top = mCircleLineStrokeWidth / 2; // 左上角ymRectF.right = width - mCircleLineStrokeWidth / 2; // 左下角xmRectF.bottom = height - mCircleLineStrokeWidth / 2; // 右下角y// 绘制圆圈,进度条背景canvas.drawArc(mRectF, -90, 360, false, mPaint);mPaint.setColor(Color.rgb(0xf8, 0x60, 0x30));canvas.drawArc(mRectF, -90, ((float) mProgress / mMaxProgress) * 360, false, mPaint);// 绘制进度文案显示mPaint.setStrokeWidth(mTxtStrokeWidth);String text = mProgress + "%";int textHeight = height / 4;mPaint.setTextSize(textHeight);int textWidth = (int) mPaint.measureText(text, 0, text.length());mPaint.setStyle(Style.FILL);canvas.drawText(text, width / 2 - textWidth / 2, height / 2 + textHeight / 2, mPaint);if (!TextUtils.isEmpty(mTxtHint1)) {mPaint.setStrokeWidth(mTxtStrokeWidth);text = mTxtHint1;textHeight = height / 8;mPaint.setTextSize(textHeight);mPaint.setColor(Color.rgb(0x99, 0x99, 0x99));textWidth = (int) mPaint.measureText(text, 0, text.length());mPaint.setStyle(Style.FILL);canvas.drawText(text, width / 2 - textWidth / 2, height / 4 + textHeight / 2, mPaint);}if (!TextUtils.isEmpty(mTxtHint2)) {mPaint.setStrokeWidth(mTxtStrokeWidth);text = mTxtHint2;textHeight = height / 8;mPaint.setTextSize(textHeight);textWidth = (int) mPaint.measureText(text, 0, text.length());mPaint.setStyle(Style.FILL);canvas.drawText(text, width / 2 - textWidth / 2, 3 * height / 4 + textHeight / 2, mPaint);}}public int getMaxProgress() {return mMaxProgress;}public void setMaxProgress(int maxProgress) {this.mMaxProgress = maxProgress;}public void setProgress(int progress) {this.mProgress = progress;this.invalidate();}public void setProgressNotInUiThread(int progress) {this.mProgress = progress;this.postInvalidate();}public String getmTxtHint1() {return mTxtHint1;}public void setmTxtHint1(String mTxtHint1) {this.mTxtHint1 = mTxtHint1;}public String getmTxtHint2() {return mTxtHint2;}public void setmTxtHint2(String mTxtHint2) {this.mTxtHint2 = mTxtHint2;}
}

Xml中配置:

  <com.jackshy.demo.view.CircleProgressBarandroid:id="@+id/circleProgressbar"android:layout_width="74dp"android:layout_height="74dp"android:layout_centerInParent="true" />

MainActivity中使用:

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;import com.jackshy.demo.view.CircleProgressBar;public class MainActivity extends Activity {private CircleProgressBar mCircleBar;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initViews();}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}private void initViews() {mCircleBar = (CircleProgressBar) findViewById(R.id.circleProgressbar);mCircleBar.setProgress(80);}}

上述还可以做成进度条的形式,这时候需要启动非UI线程调用此方法即可:

 public void setProgressNotInUiThread(int progress) {this.mProgress = progress;this.postInvalidate();}

待续。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/1383409.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

纯css制作圆形进度条

效果图大概是这样的 第一步 先定义出一个方形盒子 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>…

实现一个圆形进度条(vue)

实现方式&#xff1a;首先是用svg画两个圆&#xff0c;同圆心同半径的两个圆&#xff0c;然后把颜色都设置成透明&#xff0c;利用圆的边框来实现。给两个圆设置相同的边框宽度&#xff0c;并且设置颜色&#xff08;设置一个透明&#xff0c;一个有颜色&#xff09;&#xff1b…

药都银行冲刺上交所:年营收22.78亿 古井集团是股东

雷递网 雷建平 5月1日 亳州药都农村商业银行股份有限公司&#xff08;简称&#xff1a;“药都银行”&#xff09;日前递交招股书&#xff0c;准备在上交所主板上市。 药都银行计划募资16.38亿元。 年营收22.78亿 药都银行坐落于世界中医药之都——亳州市&#xff0c;于2005年12…

自贸港首家公务机公司海航金鹿商务正式启动运营

日前&#xff0c;海航集团旗下金鹿公务在海口设立公务机总部 -- 金鹿商务航空有限公司&#xff08;简称&#xff1a;金鹿商务&#xff09;&#xff0c;已通过中国民用航空海南安全监督管理局运行审定&#xff0c;取得中国民用航空中南地区管理局颁发的运行规范。4月29日上午9时…

内网通朋友不在线

前段时间使用内网通发现同学老师的总是不在线&#xff0c;有时候改一下IP地址&#xff0c;又可以&#xff0c;后面才发现原来可以自己设置网段地址的 设置过程见下图&#xff1a; 输入老师的IP地址的前三位即可

基于html5在线学生学籍信息管理系统

随着高校人数越来越多&#xff0c;管理高校的学生人数成为难题&#xff0c;如何更好的管理高校的入学人数&#xff1f;通过学籍的管理方式可以很好的将各年级&#xff0c;各个院校&#xff0c;各个专业的学生进行统一的管理&#xff0c;对不同的学生分门别类&#xff0c;学籍管…

爱班级电脑端下载|二维码签到

最近上网课发现爱班级的扫码功能只能在手机上进行&#xff0c;如果手动点到有时候还是会显示我没考勤&#xff0c;那有没有电脑端的爱班级下载呢&#xff1f;搜了很久发现是有的&#xff0c;但是要装个模拟器&#xff1a; 1.下载链接如下&#xff1a; 网盘链接&#xff1a; …

最新升学e网通JS逆向分析

目标网址:https://web.ewt360.com/ 重要说明:文章教程仅供参考学习,请勿用于非法用途,否则后果自负。 目录 1、接口参数分析 2、加密函数分析

2023年中国政务云行业发展概况及发展趋势分析:政务云由基础设施建设向云服务运营转变[图]

政务云是指运用云计算技术&#xff0c;统筹利用已有的机房、计算、存储、网络、安全、应用支撑、信息资源等&#xff0c;发挥云计算虚拟化、高可靠性、高通用性、高可扩展性及快速、按需、弹性服务等特征&#xff0c;为政府行业提供基础设施、支撑软件、应用系统、信息资源、运…

Java+Excel+POI+testNG基于数据驱动做一个简单的接口测试【杭州多测师_王sir】

一、创建一个apicases.xlsx放入到eclipse的resource里面&#xff0c;然后refresh刷新一下 二、在pom.xml文件中加入poi和testng的mvn repository、然后在eclipse的对应目录下放入features和plugins&#xff0c;重启eclipse就可以看到testNG了 <!--poi excel解析 --><d…

【Minecraft】Fabric Mod开发完整流程3 - 配方与挖掘等级

目录 新配方工作台配方无序合成配方有序合成配方 熔炉配方 挖掘等级与掉落物挖掘等级标准等级配置易错点分析 战利品与掉落物普通方块掉落物矿石方块掉落物 新配方 工作台配方 为便于你快速创建配方&#xff0c;可以直接去这个网站上通过拖拽的方式创建属于你的配方表&#xf…

V4L2-框架

1.概述 V4L2 是专门为linux 设备设计的一套视频框架&#xff0c;其主体框架在linux内核&#xff0c;可以理解为是整个linux系统上面的视频源捕获驱动框架。 相机驱动层位于HAL Moudle 与硬件层之间&#xff0c;借助linux 内核驱动框架&#xff0c;以文件节点的方式暴露接口给用…

vue2(2)

目录 天气案例 监视属性watch 深度监视 监视简写属性 watch对比computed 绑定class样式 条件渲染 列表渲染 天气案例 绑定事件的时候&#xff0c;xxx"yyy" yyy可以写一些简单的语句 <!DOCTYPE html> <html lang"en"> <head>…

积分代换和周期函数

昨晚上看书&#xff0c;有一个稳定随机过程的例题&#xff0c;涉及积分上下限代换、周期函数的微积分性质等知识点。这种题型以前肯定接触过&#xff0c;当下遇到了&#xff0c;思维仍然迷迷糊糊&#xff0c;像是一团乱麻&#xff0c;纠缠不清&#xff0c;照着答案思考了半天&a…

BOE(京东方)赋能荣耀Magic V2系列新品

7月12日&#xff0c;在荣耀举办的全场景新品发布会上&#xff0c;重磅推出了“革命性”折叠旗舰Magic V2系列以及首款MagicPad平板产品&#xff0c;荣耀Magic V2系列搭载BOE&#xff08;京东方&#xff09;全新一代柔性OLED折叠屏解决方案&#xff0c;以超强硬件护眼防护、超清…

开源数据库 就是免费 ,我白嫖我光荣 荣耀V2

开头还是介绍一下群&#xff0c;如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;在新加的朋友会分到2群&#xff08;共…

荣耀Magic V2折叠旗舰发布,内外双屏均支持手写笔

7月12日&#xff0c;荣耀全新一代折叠旗舰荣耀Magic V2正式发布。通过深入洞察消费者需求&#xff0c;根植于强大的技术研发实力&#xff0c;荣耀以打破边界的思维创新重新定义折叠屏手机&#xff0c;荣耀MagicV2系列实现了9.9mm的闭合态厚度&#xff0c;引领折叠屏手机进入毫米…

sip语音对讲终端怎么样?

sip语音对讲终端怎么样&#xff1f; IP语音对讲终端是一种通过网络进行语音通信的设备&#xff0c;具有以下特点&#xff1a; 1. 便捷性&#xff1a;IP语音对讲终端可以通过互联网实现远程通信&#xff0c;用户可在任何地点与他人进行语音交流&#xff0c;无需受到距离的限制…

IDEA提示:StringBuffer xxx‘ may be declared as ‘StringBuilde

如图所示&#xff0c;编写代码时遇见了如下IDEA警告&#xff1a; 原因&#xff1a;StringBuilder是线程不安全的&#xff0c;但是其效率高&#xff0c;而StringBuffer则相反&#xff0c;虽然其线程安全&#xff0c;但是效率低下。 由于 StringBuilder 相较于 StringBuffer 有速…

jenkins自动化构建保姆级教程(持续更新中)

1.安装 1.1版本说明 访问jenkins官网 https://www.jenkins.io/&#xff0c;进入到首页 点击【Download】按钮进入到jenkins下载界面 左侧显示的是最新的长期支持版本&#xff0c;右侧显示的是最新的可测试版本&#xff08;可能不稳定&#xff09;&#xff0c;建议使用最新的…