目录

前言:

实现步骤:

1.用DashPathEffect给paint加上虚线效果

2.画出进度条

3.绘制文字

4.加入动画效果


前言:

之前用华为Android系统的时候总是会想到这种虚线进度条是怎么实现的,因为直接用canvas的drawArc方法画出来的是实线,所以最近在网上搜了很多进度条相关的文章,也了解到了其中的原理,下面分享给大家。下面这两篇文章是我之前写的Android进度条相关的文章,有兴趣的朋友们可以看看:一篇文章带你了解如何打造出Android绚丽的自定义进度条https://blog.csdn.net/daydayup05/article/details/122275983Android自定义view实现圆形进度条https://blog.csdn.net/daydayup05/article/details/122150161

下面开始讲解虚线进度条的实现方法,首先看一张图:

实现步骤:

大家可以先想想这种进度条是怎么实现的?网上有各种各样的方法,也有人用path的lineTo()方法实现了类似的效果。但是我个人觉得canvas的drawArc方法也是个不错的选择,适合自己的才是最好的。

canvas.drawArc(rectF, 0, process, false, mPaint);

阅读了大量文章,最后发现改变paint的样式是最简单好用的方法。给paint设置一个effect就好了。

1.用DashPathEffect给paint加上虚线效果

DashPathEffect dashPathEffect = new DashPathEffect(new float[]{8, 6}, 0);
mPaintBack.setPathEffect(dashPathEffect);

build一下项目,看到的结果是这样的:

能实现这个效果就大功告成了,如果看过我前面两篇文章的朋友们就知道,后面的步骤就简单了,加个进度条和动画效果就可以了。

private void drawBack(Canvas canvas) {RectF rectF = new RectF(strokeWidth, strokeWidth, getWidth() - strokeWidth, getHeight() - strokeWidth);PathEffect effects = new DashPathEffect(new float[]{8, 6}, 0);mPaintBack.setPathEffect(effects);canvas.drawArc(rectF, 0, 360, false, mPaintBack);}

2.画出进度条

画进度条和画背景完全一样,只是画笔颜色和小点个数不一样。

代码如下:

 private void drawProgress(Canvas canvas) {RectF rectF = new RectF(strokeWidth, strokeWidth, getWidth() - strokeWidth, getHeight() - strokeWidth);PathEffect effects = new DashPathEffect(new float[]{8, 6}, 0);mPaint.setPathEffect(effects);canvas.drawArc(rectF, 0, process, false, mPaint);}

3.绘制文字

接下来是绘制文字,实现文字居中的效果。思路是计算出圆心,调用canvas.drawText的方法就能在canvas上面绘制文字了。这里不需要更新进度文字,所以就更省事了。

EMUI 下面的10.0.0也是一样的方法,只是给Y坐标加一下55,往下移一点就好。

    //绘制文字private void drawText(Canvas canvas) {int mTxtWidth = getTextWidth();int mTxtHeight = getTextHeight();int x = getWidth() / 2 - mTxtWidth / 2;int y = getHeight() / 2 + mTxtHeight / 4;canvas.drawText(getResources().getString(R.string.defaultTextEmui), x, y, mPaintText);}//绘制下方文字private void drawTextBlow(Canvas canvas) {int mTxtWidth = getTextWidthBlow();int mTxtHeight = getTextHeight();int x = getWidth() / 2 - mTxtWidth / 2;int y = getHeight() / 2 + mTxtHeight / 4 + 55;canvas.drawText(getResources().getString(R.string.defaultTextBelow), x, y, mPaintTextLevel);}

4.加入动画效果

    /*** 设置动画效果*/public void start() {ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 360);valueAnimator.setDuration(duration);valueAnimator.setInterpolator(new LinearInterpolator());valueAnimator.addUpdateListener(animation -> {process = (int) animation.getAnimatedValue();invalidate();});valueAnimator.start();}

最终效果:

完整代码:

package com.example.floatingwindow.widget;import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.PathEffect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.animation.LinearInterpolator;import androidx.annotation.Nullable;import com.example.floatingwindow.R;public class DottedLineProgressBar extends View {private Paint mPaint;private Paint mPaintBack;private Paint mPaintText;private Paint mPaintTextLevel;private int strokeWidth = 30;private int textSize = 22;private int textSizeBlow = 15;private long duration = 3500;private int process;public DottedLineProgressBar(Context context) {super(context);init();}public DottedLineProgressBar(Context context, @Nullable AttributeSet attrs) {super(context, attrs);init();}public DottedLineProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}public void setStrokeWidth(int width) {strokeWidth = width;}public void setTextSize(int textSize) {this.textSize = textSize;}public void setDuration(long duration) {this.duration = duration;}public void setTextSizeBlow(int textSizeBlow) {this.textSizeBlow = textSizeBlow;}//初始化画笔private void init() {mPaintBack = new Paint();//圆角矩形mPaintBack.setColor(getResources().getColor(R.color.gray));//圆角矩形颜色mPaintBack.setAntiAlias(true);// 抗锯齿效果mPaintBack.setStyle(Paint.Style.STROKE);//设置画笔样式mPaintBack.setStrokeWidth(strokeWidth);//设置画笔宽度mPaint = new Paint();mPaint.setColor(getResources().getColor(R.color.blue));mPaint.setAntiAlias(true);mPaint.setStyle(Paint.Style.STROKE);mPaint.setStrokeWidth(strokeWidth);mPaintText = new Paint();mPaintText.setAntiAlias(true);mPaintText.setStyle(Paint.Style.FILL);mPaintText.setColor(getResources().getColor(R.color.blue));mPaintText.setTextSize(sp2px(textSize));mPaintTextLevel = new Paint();mPaintTextLevel.setAntiAlias(true);mPaintTextLevel.setStyle(Paint.Style.FILL);mPaintTextLevel.setColor(getResources().getColor(R.color.gray));mPaintTextLevel.setTextSize(sp2px(textSizeBlow));}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);drawBack(canvas);drawProgress(canvas);drawText(canvas);drawTextBlow(canvas);}private void drawBack(Canvas canvas) {RectF rectF = new RectF(strokeWidth, strokeWidth, getWidth() - strokeWidth, getHeight() - strokeWidth);PathEffect effects = new DashPathEffect(new float[]{8, 6}, 0);mPaintBack.setPathEffect(effects);canvas.drawArc(rectF, 0, 360, false, mPaintBack);}private void drawProgress(Canvas canvas) {RectF rectF = new RectF(strokeWidth, strokeWidth, getWidth() - strokeWidth, getHeight() - strokeWidth);PathEffect effects = new DashPathEffect(new float[]{8, 6}, 0);mPaint.setPathEffect(effects);canvas.drawArc(rectF, 0, process, false, mPaint);}//绘制文字private void drawText(Canvas canvas) {int mTxtWidth = getTextWidth();int mTxtHeight = getTextHeight();int x = getWidth() / 2 - mTxtWidth / 2;int y = getHeight() / 2 + mTxtHeight / 4;canvas.drawText(getResources().getString(R.string.defaultTextEmui), x, y, mPaintText);}//绘制下方文字private void drawTextBlow(Canvas canvas) {int mTxtWidth = getTextWidthBlow();int mTxtHeight = getTextHeight();int x = getWidth() / 2 - mTxtWidth / 2;int y = getHeight() / 2 + mTxtHeight / 4 + 55;canvas.drawText(getResources().getString(R.string.defaultTextBelow), x, y, mPaintTextLevel);}private int getTextWidth() {String text = getResources().getString(R.string.defaultTextEmui);return (int) mPaintText.measureText(text, 0, text.length());}private int getTextWidthBlow() {String text = getResources().getString(R.string.defaultTextBelow);return (int) mPaintTextLevel.measureText(text, 0, text.length());}private int getTextHeight() {Paint.FontMetrics fm = mPaintText.getFontMetrics();return (int) Math.ceil(fm.descent - fm.ascent);}private int sp2px(int sp) {return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp,getResources().getDisplayMetrics());}/*** 设置动画效果*/public void start() {ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 360);valueAnimator.setDuration(duration);valueAnimator.setInterpolator(new LinearInterpolator());valueAnimator.addUpdateListener(animation -> {process = (int) animation.getAnimatedValue();invalidate();});valueAnimator.start();}
}

kotlin调用:

class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)dottedLineProgressBar.post {dottedLineProgressBar.start()}}
}

XML:

        <com.example.floatingwindow.widget.DottedLineProgressBarandroid:id="@+id/dottedLineProgressBar"android:layout_width="200dp"android:layout_height="200dp"android:layout_gravity="center"></com.example.floatingwindow.widget.DottedLineProgressBar>

以上就是完整的实现过程了。

项目源码:

码云仓库https://gitee.com/tu_erhongjiang/android-progress-bar

Android仿华为系统升级进度条的实现相关推荐

  1. Android (仿支付宝) 收益进度条

    一. 看效果 二.上代码 package com.framework.widget; import android.app.Activity; import android.content.Conte ...

  2. Android 仿芝麻信用进度条,自定义View仿支付宝芝麻信用分仪表盘效果

    image 前言 灵感来自几天前看到一位作者的仿芝麻信用自定义View的文章很不错,所以我换了一种方式来进行实现,写了旧版和新版芝麻信用分仪表盘的效果. 截图 这是我做的效果,还是有点差距的,嘿嘿. ...

  3. Android 仿芝麻信用进度条,Android仿支付宝上芝麻信用分雷达图

    一.首先看下支付宝上芝麻信用分的效果图: 二.思路 1.确定雷达图中心点坐标 2.绘制多边形及连接线 3.根据维度值绘制覆盖区域 4.绘制分数 5.绘制每个维度的标题文字和图标 三.实现 获取布局的中 ...

  4. progressblock 安卓自定义进度条 progressbar 高仿仿QQ下载进度条

    progressblock 安卓自定义进度条 progressbar 高仿仿QQ下载进度条 附上我在公司做下载播放项目 主要使用方法 progressBlock = (ProgressBlock) f ...

  5. Android自定义控件NumberCircleProgressBar(圆形进度条)的实现

    Android自定义控件NumberCircleProgressBar(圆形进度条)的实现

  6. [C# Control] 仿RAR式进度条 (RarProgressBar)

    Download Source & Demo System.Windows.Forms.ProgressBar的样式实在是太普通了, RarProgressBar让你多一种选择. 我并没有实现 ...

  7. Android开发之带进度条的WebView

    老套路先看效果: 直接上代码: 区分java和kotlin版本 Java版本: package com.example.progresswebview;import android.os.Bundle ...

  8. Android学习笔记(24):进度条组件ProgressBar及其子类

    ProgressBar作为进度条组件使用,它还派生了SeekBar(拖动条)和RatingBar(星级评分条). ProgressBar支持的XML属性: Attribute Name Related ...

  9. Android 动态改变SeekBar进度条颜色与滑块颜色

    Android 动态改变SeekBar进度条颜色与滑块颜色 遇到个动态改变SeekBar进度条颜色与滑块颜色的需求,如图: 有的是根据不同进度改变成不同颜色. 对于这个怎么做呢?大家都知道设置下pro ...

最新文章

  1. 与php代码类似,类似于PHP的代码_html/css_WEB-ITnose
  2. 5天玩转C#并行和多线程编程 —— 第四天 Task进阶
  3. 大数据陷阱:谁有权享有大数据,谁有权分析大数据
  4. windows下,怎么轻易拷贝一个文件的完整路径?
  5. 二、linux命令(ubuntu)
  6. OJ7627-鸡蛋的硬度【各种dp之4】
  7. java程序结构_java程序的三种结构
  8. Js判断是否在微信浏览器中打开和微信版本号
  9. 基于评论、新闻的情感倾向分析作商品的价格预测
  10. python学习之re库
  11. 要用计算机处理频谱,妙用Adobe Audition 系列教程(二):频谱分析仪 | 小众声学...
  12. 模拟城市5一直显示服务器中断,EA关闭《模拟城市5》非关键功能缓解服务器问题...
  13. AE开发之主窗体通过Base Comand和IHookHelper接口向子窗体转递图层信息方法模板
  14. 《金融学》期末小题库
  15. 大学英语(第四册)复习(原文及全文翻译)——Unit 3 - WHY DO WE BELIEVE THAT THE EARTH IS ROUND?(我们为什么相信地球是圆的?)
  16. java存储张三李四_JAVA_day14_面向对象的特征
  17. 一种直观理解Galois理论的途径
  18. 声音频率和乐器知识记录
  19. 【PANDA教程】PANDA详细教程笔记
  20. HNU软件能力实训2-17. 小A的计算器

热门文章

  1. React项目实战之租房app项目(十)个人中心模块登录访问控制项目打包部署上线
  2. jQuery实现图片跟着鼠标移动的效果
  3. 儿童产品设计,从三个方面来思考
  4. ElementUI:表格table列宽度压缩出现空白
  5. AltiumDesigner设计PCB时如何挖孔开槽?
  6. java通过poi操作word创建表格
  7. C语言txt文件的复制(Linux环境 标准IO)
  8. 谷歌2022年最受欢迎Chrome浏览器扩展程序:包含Tango,Compose AI等
  9. Linux上使用telnet连接本机IP地址端口
  10. linux开放端口,允许外部通过端口访问