Android实现带节点的进度条
作者:Silicon_Valley_DH 发布时间:2022-01-16 08:58:02
标签:Android,进度条
日常的开发中经常会需要用到自定义View,这次刚好有个需求,需要用到带有节点的进度条。东西很简单直接继承View就行了。
首先定义一些需要的属性
/**
* 背景画笔
*/
private Paint bgPaint;
/**
* 前景画笔
*/
private Paint forePaint;
/**
* 选中画笔
*/
private Paint selectPaint;
/**
* 未选中画笔
*/
private Paint unselectPaint;
/**
* 背景颜色
*/
private int bgColor = Color.parseColor("#9C9C9C");
/**
* 前景颜色
*/
private int foreColor = Color.parseColor("#8A2BE2");
/**
* 默认高度
*/
private int defaultHeight;
/**
* 节点文字
*/
private List<String> nodeList;
private List<Rect> mBounds;
/**
* 节点圆的半径
*/
private int radius;
/**
* 文字和节点进度条的top
*/
private int marginTop;
/**
* 两个节点之间的距离
*/
private int dividWidth;
/**
* 选中位置
*/
private int selectIndex;
然后在构造方法中初始化这些数据
private void init(Context context) {
radius = SizeUtils.dp2px(context,4);
defaultHeight = SizeUtils.dp2px(context,30);
marginTop = SizeUtils.dp2px(context,5);
bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
bgPaint.setColor(bgColor);
bgPaint.setStyle(Paint.Style.FILL);
forePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
forePaint.setColor(foreColor);
forePaint.setStyle(Paint.Style.FILL);
unselectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
unselectPaint.setColor(bgColor);
unselectPaint.setTextSize(SizeUtils.sp2px(context,10));
selectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
selectPaint.setColor(foreColor);
selectPaint.setTextSize(SizeUtils.sp2px(context,10));
}
设置节点文字
/**
* 设置数据
* @param nodeDatas
*/
public void setNodeList(List<String> nodeDatas){
if(nodeDatas != null){
nodeList = nodeDatas;
}
//测量文字所占用的空间
measureText();
}
/**
* 设置选中位置
* @param selectIndex
*/
public void setSelectIndex(int selectIndex){
this.selectIndex = selectIndex;
invalidate();
}
/**
* 测量文字的长宽
*/
private void measureText(){
mBounds = new ArrayList<>();
for (int i = 0; i < nodeList.size(); i++) {
Rect mBound = new Rect();
unselectPaint.getTextBounds(nodeList.get(i),0,nodeList.get(i).length(),mBound);
mBounds.add(mBound);
}
}
最后重要的步骤,开始在onDraw中绘制节点进度条和绘制文字
1、绘制灰色背景线条
if(nodeList == null || nodeList.isEmpty()){
return;
}
bgPaint.setStrokeWidth(radius/2);
//绘制灰色的背景线条
canvas.drawLine(radius,radius,getWidth()-radius,radius,bgPaint);
2、绘制节点上的圆和两个节点之间的间隔线条
//画节点圆
//每个圆相隔的距离
dividWidth = (getWidth()-radius*2)/(nodeList.size() - 1);
forePaint.setStrokeWidth(radius/2);
for (int i = 0; i < nodeList.size(); i++) {
if(i == selectIndex){
for (int j = 0; j <= i; j++) {
canvas.drawCircle(radius+ j * dividWidth, radius, radius , forePaint);
canvas.drawLine(radius,radius,j*dividWidth,radius,forePaint);
}
}else if(i>selectIndex){
canvas.drawCircle(radius + i * dividWidth, radius, radius, bgPaint);
}
}
3、绘制节点上的文字
for (int i = 0; i < nodeList.size(); i++) {
int currentTextWidth=mBounds.get(i).width();
if (i==0){
if (i==selectIndex){
canvas.drawText(nodeList.get(i), 0, radius*2 + marginTop + mBounds.get(i).height()/2, selectPaint);
}else if(i>selectIndex) {
canvas.drawText(nodeList.get(i), 0, radius*2 + marginTop + mBounds.get(i).height()/2, unselectPaint);
}
}else if (i==nodeList.size()-1){
if (i==selectIndex){
for (int j = 0; j <= i; j++) {
if(j == 0){
canvas.drawText(nodeList.get(j), 0, radius*2 + marginTop + mBounds.get(j).height()/2, selectPaint);
}else if(j == i){
canvas.drawText(nodeList.get(j), getWidth() - currentTextWidth, radius*2 + marginTop + mBounds.get(j).height()/2, selectPaint);
}else{
canvas.drawText(nodeList.get(j), radius + j * dividWidth - currentTextWidth / 2, radius*2 + marginTop + mBounds.get(j).height()/2, selectPaint);
}
}
}else if(i>selectIndex) {
canvas.drawText(nodeList.get(i), getWidth() - currentTextWidth, radius*2 + marginTop + mBounds.get(i).height()/2, unselectPaint);
}
}else {
if (i==selectIndex){
for (int j = 0; j <= i; j++) {
if(j>0){
canvas.drawText(nodeList.get(j), radius + j * dividWidth - currentTextWidth / 2, radius*2 + marginTop + mBounds.get(j).height()/2, selectPaint);
}else{
canvas.drawText(nodeList.get(j), 0, radius*2 + marginTop + mBounds.get(j).height()/2, selectPaint);
}
}
}else if(i>selectIndex) {
canvas.drawText(nodeList.get(i), radius + i * dividWidth - currentTextWidth / 2, radius*2 + marginTop + mBounds.get(i).height()/2, unselectPaint);
}
}
}
有时候可能需要的是下面这种进度条
只需要修改onDraw中绘制节点圆和文字的方法就可以了
for (int i=0; i < nodeList.size();i++) {
if (i==selectIndex){
canvas.drawCircle(radius+ i * dividWidth, radius, radius , forePaint);
}else {
canvas.drawCircle(radius + i * dividWidth, radius, radius, bgPaint);
}
}
for (int i=0; i<nodeList.size();i++){
int currentTextWidth=mBounds.get(i).width();
if (i==0){
if (i==selectIndex){
canvas.drawText(nodeList.get(i), 0, radius*2 + marginTop + mBounds.get(i).height()/2, selectPaint);
}else {
canvas.drawText(nodeList.get(i), 0, radius*2 + marginTop + mBounds.get(i).height()/2, unselectPaint);
}
}else if (i==nodeList.size()-1){
if (i==selectIndex){
canvas.drawText(nodeList.get(i), getWidth() - currentTextWidth, radius*2 + marginTop + mBounds.get(i).height()/2, selectPaint);
}else {
canvas.drawText(nodeList.get(i), getWidth() - currentTextWidth, radius*2 + marginTop + mBounds.get(i).height()/2, unselectPaint);
}
}else {
if (i==selectIndex){
canvas.drawText(nodeList.get(i), radius + i * dividWidth - currentTextWidth / 2, radius*2 + marginTop + mBounds.get(i).height()/2, selectPaint);
}else {
canvas.drawText(nodeList.get(i), radius + i * dividWidth - currentTextWidth / 2, radius*2 + marginTop + mBounds.get(i).height()/2, unselectPaint);
}
}
}
点击节点进行节点切换
// 实现节点切换,把注释打开就行了
@Override
public boolean onTouchEvent(MotionEvent event) {
float eventX;
float eventY;
int i = event.getAction();
if (i == MotionEvent.ACTION_DOWN) {
} else if (i == MotionEvent.ACTION_MOVE) {
} else if (i == MotionEvent.ACTION_UP) {
eventX = event.getX();
eventY = event.getY();
//计算选中的index
float select = eventX / dividWidth;
float xs = select - (int) (select);
//selectIndex = (int) select + (xs > 0.5 ? 1 : 0);
}
//invalidate();
return true;
}
来源:https://blog.csdn.net/u013855006/article/details/81157618
0
投稿
猜你喜欢
- 使用java制作一款简单的扫雷游戏,供大家参考,具体内容如下import java.util.*;public class nephelok
- 一、IDEA自带打包插件内容:此种方式可以自己选择制作胖包或者瘦包,但推荐此种方式制作瘦包。输出:输出目录在out目录下流程步骤:第一步:
- 最近遇到一个调试很久的问题,MyBatis 查询 Oracle 数据库查询结果与在客户端查询结果不一致。问题引入测试表、测试数据创建测试表、
- HashMap和HashTable,这二者的区别经常被别人问起,今天在此总结一下。(一)继承的历史不同public class
- Spring Security中的内置过滤器顺序是怎么维护的?我想很多开发者都对这个问题感兴趣。本篇我和大家一起探讨下这个问题。HttpSe
- 1、项目启动时报错如下Description:The bean 'securityManager', defined in
- 本文实例为大家分享了Java流布局图形界面编写代码,供大家参考,具体内容如下package jisuanqi;import java.awt
- 废话不多说了,直接给大家贴关键代码了。具体代码如下所示:using System;using System.Collections.Gene
- Java 和 Groovy 中的映射map都是非常通用的,它允许关键字key和值value为任意类型,只要继承了 Object&n
- 使用lamda表达式对list进行求和Lambda 表达式是 JDK8 的一个新特性,最近写项目中求和计算使用的较多,写篇文章记录下。1、实
- 封面图下个季度的目标是把前端监控相关的内容梳理出来,梳理出来之后可能会在公司内部做个分享~Flutter应用程序既括代码也包括一些其他的资产
- 1.通过UnityHub安装unityUnityHub下载路径,UnityHub安装按照步骤来就可以了。打开UnityHub,点安装。3.选
- 我们平时使用的一些常见队列都是非阻塞队列,比如PriorityQueue、LinkedList(LinkedList是双向链表,它实现了De
- MyBatis-Plus是通过version机制实现乐观锁的。大致思路:取出记录,携带记录的当前version;更新记录的时候,比较记录当前
- 前言 在软件开发中,我们通常会遇到一种场景,比如某个请求,会依次经过系统中的很多个模块来处理,如果某个模
- 本文实例讲述了C#启动进程的几种常用方法。分享给大家供大家参考。具体如下:1.启动子进程,不等待子进程结束private void simp
- 本文实例为大家分享了MVPXlistView上拉下拉展示的具体代码,供大家参考,具体内容如下抽基类package com.gs.gg.day
- 源码学习的好处不用多说,Mybatis源码量少、逻辑简单,将写个系列文章来学习。SqlSessionMybatis的使用入口位于org.ap
- 本文以实例形式简单讲述了C#对象为Null模式(Null Object Pattern),分享给大家供大家参考。具体实现方法如下:所谓的&q
- 今天学习了Mybatis执行存储,感觉不是那么好用,可能是我没用习惯。我先在SQLSERVER创建存储alter procedure usp