android给方法设置进度,Android自定义View实现多节点进度条功能的方法

2023-05-16

Android自定义View实现多节点进度条功能的方法

发布时间:2020-07-28 16:05:13

来源:亿速云

阅读:122

作者:小猪

这篇文章主要讲解了Android自定义View实现多节点进度条功能的方法,内容清晰明了,对此有兴趣的小伙伴可以学习一下,相信大家阅读完之后会有帮助。

前言

最近项目有一个节点进度条的小需求,完成后,想分享出来希望可以帮到有需要的同学。

真机效果图

ea0500e6601fae390130e252af11524b.png

04aee661af81c624fd09227c33a03307.png

自定义View完整代码

开箱即用~,注释已经炒鸡详细了

/**

* @description: 节点进度条

* @author: DMingO

* @date: 2020/4/15

*/

public class PointProcessBar extends View {

/**

* 未选中时的连线画笔

*/

private Paint mLinePaint;

/**

* 选中时的连线画笔

*/

private Paint mLineSelectedPaint;

/**

* 未选中时的文字画笔

*/

private Paint mTextPaint;

/**

* 选中时的文字画笔

*/

private Paint mTextSelPaint;

/**

* 未选中时的实心圆画笔

*/

private Paint mCirclePaint;

/**

* 选中时的内部实心圆画笔

*/

private Paint mCircleSelPaint;

/**

* 选中时的边框圆画笔

*/

private Paint mCircleStrokeSelPaint;

/**

* 未选中时的线,节点圆的颜色

*/

private int mColorUnselected = Color.parseColor("#1ca8b0d9");

/**

* 选中时的颜色

*/

private int mColorSelected = Color.parseColor("#61A4E4");

/**

* 未选中的文字颜色

*/

private int mColorTextUnselected = Color.parseColor("#5c030f09");

/**

* 绘制的节点个数,由底部节点标题数量控制

*/

int circleCount ;

/**

* 连线的高度

*/

float mLineHeight = 7f;

//圆的直径

float mCircleHeight = 50f;

float mCircleSelStroke = 8f;

float mCircleFillRadius = 15f;

//文字大小

float mTextSize = 35f;

//文字离顶部的距离

float mMarginTop = 40f;

/**

* 首个圆向中心偏移的距离

*/

float marginLeft = 30f;

/**

* 最后一个圆向中心偏移的距离

*/

float marginRight = marginLeft;

/**

* 每个节点相隔的距离

*/

float divideWidth;

int defaultHeight;

/**

* 节点底部的文字列表

*/

List textList = new ArrayList<>();

/**

* 文字同宽高的矩形,用来测量文字

*/

List mBounds;

/**

* 存储每个圆心在同一直线上的节点圆的 x 坐标值

*/

List circleLineJunctions = new ArrayList<>();

/**

* 选中项集合

*/

Set selectedIndexSet = new HashSet<>();

public PointProcessBar(Context context) {

super(context);

}

public PointProcessBar(Context context, @Nullable AttributeSet attrs) {

super(context, attrs);

initPaint();

}

public PointProcessBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

public PointProcessBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {

super(context, attrs, defStyleAttr, defStyleRes);

}

/**

* 初始化画笔属性

*/

private void initPaint(){

mLinePaint = new Paint();

mLineSelectedPaint = new Paint();

mCirclePaint = new Paint();

mTextPaint = new Paint();

mCircleStrokeSelPaint = new Paint();

mTextSelPaint=new Paint();

mCircleSelPaint = new Paint();

mLinePaint.setColor(mColorDef);

//设置填充

mLinePaint.setStyle(Paint.Style.FILL);

//笔宽像素

mLinePaint.setStrokeWidth(mLineHeight);

//锯齿不显示

mLinePaint.setAntiAlias(true);

mLineSelectedPaint.setColor(mColorSelected);

mLineSelectedPaint.setStyle(Paint.Style.FILL);

mLineSelectedPaint.setStrokeWidth(mLineHeight);

mLineSelectedPaint.setAntiAlias(true);

mCirclePaint.setColor(mColorDef);

//设置填充

mCirclePaint.setStyle(Paint.Style.FILL);

//笔宽像素

mCirclePaint.setStrokeWidth(1);

//锯齿不显示

mCirclePaint.setAntiAlias(true);

//选中时外框空心圆圈画笔

mCircleStrokeSelPaint.setColor(mColorSelected);

mCircleStrokeSelPaint.setStyle(Paint.Style.STROKE);

mCircleStrokeSelPaint.setStrokeWidth(mCircleSelStroke);

mCircleStrokeSelPaint.setAntiAlias(true);

//选中时的内部填充圆画笔

mCircleSelPaint.setStyle(Paint.Style.FILL);

mCircleSelPaint.setStrokeWidth(1);

mCircleSelPaint.setAntiAlias(true);

mCircleSelPaint.setColor(mColorSelected);

//普通状态的文本 画笔

mTextPaint.setTextSize(mTextSize);

mTextPaint.setColor(mColorTextDef);

mTextPaint.setAntiAlias(true);

mTextPaint.setTextAlign(Paint.Align.CENTER);

//选中后的文本画笔

mTextSelPaint.setTextSize(mTextSize);

mTextSelPaint.setColor(mColorSelected);

mTextSelPaint.setAntiAlias(true);

mTextSelPaint.setTextAlign(Paint.Align.CENTER);

}

/**

* 测量文字的长宽,将文字视为rect矩形

*/

private void measureText(){

mBounds = new ArrayList<>();

for(String name : textList){

Rect mBound = new Rect();

mTextPaint.getTextBounds(name, 0, name.length(), mBound);

mBounds.add(mBound);

}

}

/**

* 测量view的高度

*/

private void measureHeight(){

if (mBounds!=null && mBounds.size()!=0) {

defaultHeight = (int) (mCircleHeight + mMarginTop + mCircleSelStroke + mBounds.get(0).height()/2);

} else {

defaultHeight = (int) (mCircleHeight + mMarginTop+mCircleSelStroke);

}

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);

int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);

int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);

int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);

//宽高都设置为wrap_content

if(widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST){

//宽设置为wrap_content

setMeasuredDimension(widthSpecSize,defaultHeight);

}else if(widthSpecMode == MeasureSpec.AT_MOST){

setMeasuredDimension(widthSpecSize,heightSpecSize);

}else if(heightSpecMode == MeasureSpec.AT_MOST){

//高设置为wrap_content

setMeasuredDimension(widthSpecSize, defaultHeight);

}else{

//宽高都设置为match_parent或具体的dp值

setMeasuredDimension(widthSpecSize, heightSpecSize);

}

}

@Override

protected void onDraw(Canvas canvas) {

//若未设置节点标题或者选中项的列表,则取消绘制

if (textList == null || textList.isEmpty() ||

selectedIndexSet == null || selectedIndexSet.isEmpty() ||

mBounds == null || mBounds.isEmpty()) {

return;

}

//画灰色圆圈的个数

circleCount=textList.size();

//每个圆相隔的距离(重要),可以通过这个调节节点间距

divideWidth = (getWidth() - mCircleHeight ) / (circleCount - 1);

//绘制文字和圆形

for (int i=0; i < circleCount ;i++){

float cx;

float cy;

float textX;

if (i==0){

//第一个节点,圆心需要向右偏移

cx = mCircleHeight / 2 + i * divideWidth + marginLeft;

cy = mCircleHeight / 2 + mCircleSelStroke;

textX = cx;

circleLineJunctions.add(cx + mCircleHeight / 2);

}else if (i==textList.size()-1){

//最后一个节点,圆心需要向左偏移

cx = mCircleHeight / 2 + i * divideWidth - marginRight;

cy = mCircleHeight / 2 + mCircleSelStroke;

textX = cx;

circleLineJunctions.add(cx - mCircleHeight / 2);

}else {

//中间部分的节点

cx = mCircleHeight / 2 + i * divideWidth;

cy = mCircleHeight / 2+mCircleSelStroke;

textX = cx;

circleLineJunctions.add(cx - mCircleHeight / 2);

circleLineJunctions.add(cx + mCircleHeight / 2);

}

if (getSelectedIndexSet().contains(i)){

//若当前位置节点被包含在选中项Set中,判定此节点被选中

canvas.drawCircle(cx , cy, mCircleHeight / 2, mCircleStrokeSelPaint);

canvas.drawCircle(cx, cy, mCircleFillRadius, mCircleSelPaint);

canvas.drawText(textList.get(i), textX, (float) (mCircleHeight + mMarginTop +mCircleSelStroke+mBounds.get(i).height()/2.0), mTextSelPaint);

}else {

//若当前位置节点没有被包含在选中项Set中,判定此节点没有被选中

canvas.drawCircle(cx , cy, mCircleHeight / 2, mCirclePaint);

canvas.drawText(textList.get(i), textX, (float) (mCircleHeight + mMarginTop +mCircleSelStroke+mBounds.get(i).height()/2.0), mTextPaint);

}

}

for(int i = 1 , j = 1 ; j <= circleLineJunctions.size() && ! circleLineJunctions.isEmpty() ; ++i , j=j+2){

if(getSelectedIndexSet().contains(i)){

canvas.drawLine(circleLineJunctions.get(j-1),mCircleHeight/2+mCircleSelStroke,

circleLineJunctions.get(j) ,mCircleHeight/2+mCircleSelStroke,mLineSelectedPaint);

}else {

canvas.drawLine(circleLineJunctions.get(j-1),mCircleHeight/2+mCircleSelStroke,

circleLineJunctions.get(j) ,mCircleHeight/2+mCircleSelStroke,mLinePaint);

}

}

}

/**

* 供外部调用,显示控件

* @param titles 底部标题内容列表

* @param indexSet 选中项Set

*/

public void show(List titles , Set indexSet){

if(titles != null && ! titles.isEmpty()){

this.textList = titles;

}

if(indexSet != null && ! indexSet.isEmpty()){

this.selectedIndexSet = indexSet;

}

measureText();

measureHeight();

//绘制

invalidate();

}

/**

* 更新底部节点标题内容

* @param textList 节点标题内容列表

*/

public void refreshTextList(List textList) {

this.textList = textList;

measureText();

measureHeight();

invalidate();

}

/**

* 获取节点选中状态

* @return 节点选中状态列表

*/

public Set getSelectedIndexSet() {

return selectedIndexSet;

}

/**

* 更新选中项

* @param set 选中项Set

*/

public void refreshSelectedIndexSet(Set set) {

this.selectedIndexSet = set;

invalidate();

}

}

注意点控件的节点总个数是与传入的节点底部标题列表中元素个数控制(相同)的,简而言之就是传入的标题列表中有多少个标题,节点就会绘制多少个

控件通过show方法进行View的初始化和显示内容,传入节点标题列表和节点选中项集合,控制View的选中状态和显示的内容

控件初始化显示后,可以通过refreshTextList(),refreshSelectedIndexSet() 更新标题和选中项

具体不同的颜色,大小可以具体在View中调整

总结

可以看到效果不复杂,因此自定义View的代码行数不多,也很容易看懂,直接拿走代码即可在项目中食用啦。

由于不同项目设计稿会有不同,这里也仅仅给有需要的同学一个思路,可以改造具体实现代码~

看完上述内容,是不是对Android自定义View实现多节点进度条功能的方法有进一步的了解,如果还想学习更多内容,欢迎关注亿速云行业资讯频道。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

android给方法设置进度,Android自定义View实现多节点进度条功能的方法 的相关文章

  • 位和结构体寄存器访问方法(转)

    1 2 1 传统 define 方法 1 2 外设位域结构体方法综述 DSP281x 头文件和外设示例使用位域结构体方法 xff0c 映射和访问基于F28x 外设寄存器 本节将介绍这种方法 xff0c 并把它和传统的 define 方法加以
  • 关于将函数写入头文件问题(分离式编译)

    如果某些函数在其他很多 cpp 文件中被调用 xff0c 那么为了避免写大量重复的代码以及让代码量更小一些 xff0c 我们可以将这些函数写头文件中 xff0c 然后其他 cpp 文件只需要引用该头文件然后就可以使用包含在头文件中的函数了
  • SpringSecurity配置跨域访问

    说明 java后端web服务有很多种方法可以实现跨域访问 xff0c 配置很简单 xff0c 今天这里我们用SpringSecurity的方式配置跨域访问 xff0c 配置方法如下 xff1a span class token keywor
  • 嵌入式C语言开发---存储器与寄存器

    概述 xff1a 讲述如何使用C语言来对底层寄存器进行封装 内容 xff1a 存储器映射寄存器与寄存器映射C语言访问寄存器 存储器映射 程序存储器 数据存储器 寄存器和I O 端口排列在同一个顺序的4 GB 地 址空间内 存储器映射 xff
  • httplib用法

    httplib的内容上是很多 xff0c 也比较简单 以下是一个非常简单的例子 xff0c 使用httplib获取google首页的html xff1a import httplib conn 61 httplib HTTPConnecti
  • HTTP认证之摘要认证——Digest(一)

    导航 HTTP认证之基本认证 Basic xff08 一 xff09 HTTP认证之基本认证 Basic xff08 二 xff09 HTTP认证之摘要认证 Digest xff08 一 xff09 HTTP认证之摘要认证 Digest x
  • Linux 文件名和路径的最大长度

    在x86 64 Linux下 xff0c 文件名的最大长度是255个字符 characters xff0c 文件路径的最大长度是4096字符 characters xff0c 即可以包含16级的最大文件长度的路径 在 lt limits h
  • Django之auth

    一 xff1a auth基础 xff08 1 xff09 作用 xff1a django提供给开发人员 对用户进行操作的模块的 例如 xff1a 登录 注册 认证 注销等等 xff08 2 xff09 使用方式 from django co
  • [JavaSE 源码分析] 关于HashMap的个人理解

    目录 HashMap是什么 HashMap的底层数据结构是什么 table容量为什么必须是二的倍数 table容量怎么做到二的倍数 Entry是怎样的结构 Node Entry在HashMap中的具体实现处理hash冲突的方法HashMap
  • HIS(LIS、PACS、RIS、EMR)系统简介

    HIS xff08 LIS PACS RIS EMR xff09 系统简介 HIS xff1a 医院信息系统 Hospital Information System HIS xff0c 利用电子计算机和通讯设备 xff0c 为医院所属各部
  • jackson使用问题:mapper.readValue()将JSON字符串转反序列化为对象失败或异常

    问题根源 xff1a 转化目标实体类的属性要与被转JSON字符串总的字段 一 一对应 xff01 字符串里可以少字段 xff0c 但绝对不能多字段 先附上我这段出现了问题的源码 xff1a 1 接收并转化相应的参数 需要在pom xml中引
  • SpringSecurity集成oauth2(jwt)

    版本 springboot版本 xff1a 2 2 7 RELEASE spring security oauth2版本 xff1a 2 3 6 RELEASE 主要依赖 span class token tag span class to
  • 微信小程序开发——点击按钮获取用户授权没反应或反应很慢的解决方法

    异常描述 xff1a 点击按钮获取用户手机号码 xff0c 有的时候会出现点击无反应 或很久之后才弹出用户授权获取手机号码的弹窗 xff0c 这种情况下 xff0c 也会出现点击穿透的问题 xff08 详见 xff1a 微信小程序开发 连续
  • 09-cmake语法-add_dependencies()

    在编译器的命令行上 xff0c 为当前路径以及下层路径的源文件加入一些define flag 这个命令可以用来引入任何flag xff0c 但是它的原意是用来引入预处理器的定义 那些以 D或 D开头的 看起来像预处理器定义的flag xff
  • WordPress教程之判断文章所属分类函数in_category、is_category

    最近自己在修改一个采用Wordpress程序的博客的时候需要用到一个特殊的功能 xff1a 我需要判断这篇文章是属于哪些分类 xff0c 如果属于我设定的分类下的文章 xff0c 则输出一个DIV内容 按道理说实现这个功能应该不算太难 xf
  • 对SIP摘要认证方案的理解

    一 口令认证常见机制 基于口令认证的系统一般有以下几种口令验证方式 xff1a 1 客户端以明文形式将用户名密码通过网络发送到服务器 xff0c 服务器与已经保存在服务端的用户名密码进行比较 xff0c 一致则通过验证 xff1b HTTP
  • 第三方库引用:头文件和库文件

    附加库与头文件目录 xff1a 1 头文件 头文件引用时的查找路径 xff1a c c 43 43 gt general 将第三方库的头文件所在文件夹包含进去 影响到文件中 h头文件的引用路径的写法 源码 xff1a include a h
  • 深入理解Java虚拟机JVM

    JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java exe来完成 通过下面4步来完成JVM环境 1 创建JVM装载环境和配置 2 装载JVM dll 3 初始化JVM dll并挂界到JNIENV JNI调用接口 实例 4
  • Kubernetes Pod的数据卷Volume

    概述 由于容器本身是非持久化的 xff0c 因此需要解决在容器中运行应用程序遇到的一些问题 首先 xff0c 当容器崩溃时 xff0c kubelet将重新启动容器 xff0c 但是写入容器的文件将会丢失 xff0c 容器将会以镜像的初始状
  • Nodejs模块依赖的几种方式

    a js function add x y return x 43 y function sub x y return x y let str 61 34 God like 34 const arr 61 1 2 3 4 exports a

随机推荐

  • 9.26

    以后可能会在每次考试后 当然极大概率咕咕咕 找一道题讲讲其实是三道题太多了 那么既然量减了 质量就会提上去了也不一定 一次可能会根据某一道题说些思路 反正也没人看 随便写一些留着自己用好了 于是本期节目为您带来 换根dp 这东西好像考了两三
  • 9.28

    昨天的大概就咕咕咕了 今天说差分 多图预警 于是 进入正题 今天的主题是差分 但我们或许也应该先说说前缀和 众所周知 差分是前缀和的逆运算 跟我一起念三遍 差分是前缀和的逆运算 差分是前缀和的逆运算 差分是前缀和的逆运算 差分是前缀和的逆运
  • sde for oracle 10g 安装和链接

    sde版本9 3 xff0c oracle 的版本最好是 10 2 就是 R2 xff0c 如果是10 1的话会很麻烦 xff08 我没有装成功 xff09 几个容易忘记的地方 xff1a catalog的连接时的设置 xff1a Serv
  • R语言-画柱形图

    barplot 函数 1 柱形图 gt sales lt read csv 34 citysales csv 34 header 61 TRUE 读取数据 gt barplot sales ProductA names arg 61 sal
  • 靶机大全

    本指南主要通过介绍一些常用渗透环境 给pentester们以自己修炼的机会 并配合一些常规的pentest tools达到学习目的 名称 WebGoat 项目地址 http www owasp org index php OWASP Web
  • Cannot create property 'default' on boolean 'true'"

    解决办法 xff1a 删除node modules包 xff0c 重新npm i 转载于 https www cnblogs com 92xcd p 10443538 html
  • 怎么增加照片的KB大小

    之前都是要想办法压缩图片的大小 今天有人发来一张1 8MB的图片让我帮忙调到30MB左右 一下子放大这么多着实有点茫然 之后想到了一个办法 首先把图片占用体积变大 xff0c 是不会增加清晰度的 xff0c 而减小占用体积却会降低清晰度 第
  • 参数 返回值

    1 函数 函数是对功能的封装 语法 def 函数名 形参列表 函数体 代码块 return 调用 函数名 实参列表 2 返回值 return 在函数执行的时候 如果遇到return 直接返回 1 如果函数什么都不写 不写return 没有返
  • 抽象类调用自己的抽象方法,实现来自实现类(很常用)

    直接上代码 public abstract class Parent public abstract void dosomething public void say dosomething System out println 34 ww
  • 学习笔记:51单片机(STC89C52)如何定时10ms

    1 定时器如何定时 首先大致描述一下定时器的定时原理 xff0c 其实本质就一句话 xff1a 每经过一个机器周期 xff0c 寄存器就加1 这里就又要解释什么是时钟周期 xff0c 什么是机械周期 我们的51单片机无论是开发板还是最小系统
  • cmake 的使用

    官网教程 xff1a https cmake org cmake tutorial 第一个简单的例子 源文件 xff1a tutorial cpp 1 A simple program that computes the square ro
  • python 读取一个文件夹下的所jpg文件保存到txt中

    最近需要使用统计一个目录下的所有文件 xff0c 使用python比较方便 xff0c 就整理了一下代码 1 import os 2 3 def gci filepath 4 files 61 os listdir filepath 5 f
  • cmake 单个目录多个文件的情况

    参考 xff1a https www hahack com codes cmake 源文件一共有三个 xff1a main cpp MathFunctions h MathFunctions cpp 文件内容分别如下 xff1a main
  • k8s config配置文件

    接着上面的博客继续写 pwd gt etc kubernetes cat config kubernetes system config The following values are used to configure various
  • html5手机web页面底部菜单

    一 效果图 二 HTML代码 lt header class 61 34 text center 34 gt TOP lt header gt lt div id 61 34 content 34 gt lt div gt lt div i
  • redis hset hmset过期时间

    hmset m k v 127 0 0 1 6379 gt hset m k v integer 1 127 0 0 1 6379 gt hget m k 34 v 34 127 0 0 1 6379 gt expire m 30 inte
  • Mac下 .bash_profile 和 .zshrc 两者之间的区别

    这是我碰到的需要 source 之后才能使用环境变量的问题 xff0c 我就不细究了 xff0c 说说我的看法 bash profile 中修改环境变量只对当前窗口有效 xff0c 而且需要 source bash profile才能使用
  • h5页面使用js实现保存当前图片到手机相册

    很可惜 xff0c 这个鬼东西微信内置浏览器不适用 页面 xff1a lt doctype html gt lt html gt lt head gt lt meta charset 61 34 UTF 8 34 gt lt meta co
  • HTTP认证之基本认证——Basic(一)

    导航 HTTP认证之基本认证 Basic xff08 一 xff09 HTTP认证之基本认证 Basic xff08 二 xff09 HTTP认证之摘要认证 Digest xff08 一 xff09 HTTP认证之摘要认证 Digest x
  • android给方法设置进度,Android自定义View实现多节点进度条功能的方法

    Android自定义View实现多节点进度条功能的方法 发布时间 xff1a 2020 07 28 16 05 13 来源 xff1a 亿速云 阅读 xff1a 122 作者 xff1a 小猪 这篇文章主要讲解了Android自定义View