android 自定义八边形进度条

自定义八边形动画效果图如下图片: ![Alt](https://img-home.csdnimg.cn/images/20220524100510.pn
绘制步骤:
1.先绘制橙色底部八边形实心
2.黑色画笔绘制第二层,让最外层显示一条线条宽度即可
3.再用黄色画笔绘制黄色部分
4.使用渐变画笔根据当前进度绘制覆盖黄色部分
5.使用黑色画笔根据当前进度绘制刻度条
6.黑色画笔绘制第三层留出黄色部分的宽度

完整代码

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RadialGradient;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;public class EightView extends View {private Paint mPaint;private Paint roundPaint;private Paint bgPaint;private float mR, mCx, mCy,mR1,mR2;private static final int mN = 8;private static final float DEGREES_UNIT = 360 / mN; //正N边形每个角  360/mN能整除private int width = 0;private int height = 0;//外部描边色:#d06d38private int[] colors = new int[]{Color.parseColor("#e3682f"),Color.parseColor("#e3682f"),Color.parseColor("#e59f3a"),Color.parseColor("#e59f3a"),};public EightView(Context context) {this(context, null);}public EightView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public EightView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);//   PorterDuffXfermode porterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);//绘制8边形外环mPaint = new Paint();mPaint.setColor(Color.parseColor("#e3682f"));mPaint.setStyle(Paint.Style.STROKE);mPaint.setStrokeCap(Paint.Cap.ROUND); // 设置转弯处为圆角// 当绘图样式为 STROKE 时,该方法用于指定线条连接处的拐角样式,能使绘制的图形更加平滑mPaint.setStrokeJoin(Paint.Join.ROUND);mPaint.setStrokeWidth(50F);//  mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST));mPaint.setAntiAlias(true);//绘制刻度圆,然后进行裁剪,按照外环的大小roundPaint=new Paint();roundPaint.setStyle(Paint.Style.FILL);roundPaint.setAntiAlias(true);roundPaint.setStrokeWidth(8);//  roundPaint.setXfermode(porterDuffXfermode);//绘制黑色背景,bgPaintbgPaint=new Paint();bgPaint.setColor(Color.YELLOW);bgPaint.setStyle(Paint.Style.FILL);bgPaint.setAntiAlias(true);//    bgPaint.setXfermode(porterDuffXfermode);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);width = getSize(widthMeasureSpec);height = getSize(heightMeasureSpec);if (width < height) {height = width;} else {width = height;}setMeasuredDimension(width, height);}private int getSize(int measureSpec) {int mySize = 100;int mode = MeasureSpec.getMode(measureSpec);int size = MeasureSpec.getSize(measureSpec);switch (mode) {case MeasureSpec.UNSPECIFIED: {//如果没有指定大小:就设置为默认大小mySize = 100;break;}case MeasureSpec.AT_MOST: //如果测里模式是最大取值为size,我们将大小取最大值,你也可以取其他值case MeasureSpec.EXACTLY: {//如果是固定的大小,那就不要去改变它mySize = size;break;}}return mySize;}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);float mW = getMeasuredWidth();float mH = getMeasuredHeight();if (mW < mH) {mH = mW;} else {mW = mH;}//----mCx-230.0---mCy-230.0---mR-172.5mCx = mW / 2;mCy = mH / 2;//mCx和mCy中的较小者mR = Math.min(mCx, mCy) / 4 * 3;mR1 = mW/7*3;mR2=mR1-5;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.rotate(23, mCx, mCy);
//        canvas.rotate(-45, mCx, mCy);canvas.drawColor(bgColor);mPaint.setColor(Color.parseColor("#e3682f"));float d1 = (float) (2 * mR1 * Math.sin(Math.toRadians(DEGREES_UNIT / 2)));float c1 = mCy - mR1;float y1 = (d1 * d1 + mCy * mCy - c1 * c1 - mR1 * mR1) / (2 * (mCy - c1));float x1 = (float) (mCx + Math.sqrt(-1 * c1 * c1 + 2 * c1 * y1 + d1 * d1 - y1 * y1));for (int i = 0; i < 8; i++) {canvas.save();canvas.rotate(DEGREES_UNIT * i, mCx, mCy);canvas.drawLine(mCx, c1, x1, y1, mPaint);canvas.restore();}mPaint.setColor(bgColor);float d2 = (float) (2 * mR2 * Math.sin(Math.toRadians(DEGREES_UNIT / 2)));float c2 = mCy - mR2;float y2 = (d2 * d2 + mCy * mCy - c2 * c2 - mR2 * mR2) / (2 * (mCy - c2));float x2 = (float) (mCx + Math.sqrt(-1 * c2 * c2 + 2 * c2 * y2 + d2 * d2 - y2 * y2));for (int i = 0; i < 8; i++) {canvas.save();canvas.rotate(DEGREES_UNIT * i, mCx, mCy);// canvas.drawLine(mCx, mCy, mCx, c, mPaint);//中间的连接线canvas.drawLine(mCx, c2, x2, y2, mPaint);canvas.restore();}//离屏绘制int layer1 = canvas.saveLayer(0, 0, width, height, mPaint);int layer2 = canvas.saveLayer(0, 0, width, height, bgPaint);int layer3 = canvas.saveLayer(0, 0, width, height, roundPaint);mPaint.setColor(Color.parseColor("#e59f3a"));float d = (float) (2 * mR * Math.sin(Math.toRadians(DEGREES_UNIT / 2)));float c = mCy - mR;float y = (d * d + mCy * mCy - c * c - mR * mR) / (2 * (mCy - c));float x = (float) (mCx + Math.sqrt(-1 * c * c + 2 * c * y + d * d - y * y));for (int i = 0; i < 8; i++) {canvas.save();canvas.rotate(DEGREES_UNIT * i, mCx, mCy);canvas.drawLine(mCx, c, x, y, mPaint);canvas.restore();}if (gradient==null){gradient =new RadialGradient(mCx,mCy, mCx/5,colors,null, Shader.TileMode.MIRROR);}bgPaint.setShader(gradient);/*** left–矩形左侧的X坐标* top–矩形顶部的Y坐标* right–矩形右侧的X坐标* bottom–矩形底部的Y坐标*/if (rectF==null){rectF = new RectF(0, 0, width, height);}bgPaint.setXfermode(mode);canvas.drawArc(rectF, 67, indexCircle, true, bgPaint);//底部圆//最后将画笔去除XfermodebgPaint.setXfermode(null);//绘制刻度线canvas.translate(width / 2, height / 2);roundPaint.setXfermode(mode);roundPaint.setColor(bgColor);//90度12根,360度48根 270度36  //90度8根,360度30根int index=indexCircle*46/360;for (int i = 0; i < index; i++) {//共48等分,根据绘制的角度更改canvas.save();//画布保存int degress=i * 8+67;if (degress>360){degress=degress-360;}canvas.rotate(degress);//绘制图标的旋转360 + i * 36
//            int alpha = (int) ((i / 60f * 255 + circleAlpha) % 255);
//            mPaint.setAlpha(alpha);//设置画笔的透明度[0-255],0是完全透明,255是完全不透明canvas.translate(width/2-mCircleWidth, 0);//绘图坐标的平移。canvas.drawLine(0, 0, mCircleWidth, 0, roundPaint);//绘制线.drawLine,drawLines绘制多条线canvas.restore();//合并保存后的图层}//最后将画笔去除XfermoderoundPaint.setXfermode(null);//恢复图层canvas.restoreToCount(layer1);canvas.restoreToCount(layer2);canvas.restoreToCount(layer3);}private  RadialGradient gradient;private  RectF rectF;private PorterDuffXfermode mode=new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP);private int mCircleWidth = 120;//圆弧的长度private int indexCircle=0;private int bgColor=Color.BLACK;public void setBgColor(int BgColor){bgColor=BgColor;}public void setAngle(int mStepNum) {mStepNum=360-mStepNum;if (mStepNum > 360) {mStepNum = 360;}if (mStepNum < 0) {mStepNum = 0;}this.indexCircle = mStepNum;invalidate();}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自动驾驶预测-决策-规划-控制学习(5):图像分割与语义分割入门

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 论文题目&#xff1a;Evolution of Image Segmentation using Deep Convolutional Neural Network: A Survey前言&#xff1a;图像分割与语义分割一、图像分割是什么…

重新认识Word——页眉页脚

重新认识Word——页眉页脚 节设置页脚第X页&#xff0c;共Y页 奇偶页不同页眉包含章节号清除页眉横线 我们之前已经全面的构建了我们的文章&#xff0c;现在我们来了解一下&#xff0c;我们毕业论文的页眉&#xff08;页面信息&#xff09;页脚&#xff08;页码&#xff09;的设…

Clickhouse: One table to rule them all!

前面几篇笔记我们讨论了存储海量行情数据的个人技术方案。它们之所以被称之为个人方案&#xff0c;并不是因为性能弱&#xff0c;而是指在这些方案中&#xff0c;数据都存储在本地&#xff0c;也只适合单机查询。 数据源很贵 – 在这个冬天&#xff0c;我们已经听说&#xff0…

JMeter请求参数Parameters,带中文或特殊字符(+/=)时,例如登录密码或者token等,需要勾选编码

以前的登录接口密码参数不包含特殊字符&#xff0c;为了安全&#xff0c;产品今天修改了需求&#xff0c;密码必须由数字&#xff0c;字母和特殊字符构成&#xff0c;之前利用JMeter接口编写的脚本报错了&#xff0c;调整了一下&#xff0c;里面踩了一点坑&#xff0c;记录下来…

给科研人的 ML 开源发布工具包

什么是开源发布工具包&#xff1f; 恭喜你的论文成功发表&#xff0c;这是一个巨大的成就&#xff01;你的研究成果将为学界做出贡献。 其实除了发表论文之外&#xff0c;你还可以通过发布研究的其他部分&#xff0c;如代码、数据集、模型等&#xff0c;来增加研究的可见度和采…

c语言嵌套循环

c语言嵌套循环 c语言嵌套循环 c语言嵌套循环一、c语言嵌套循环格式二、嵌套循环案例九九惩罚口诀 一、c语言嵌套循环格式 for(初始值&#xff1b;表达式&#xff1b;表达式) {for&#xff08;初始值&#xff1b;表达式&#xff1b;表达式&#xff09;{代码} }int main() {for (…

【java八股文】之计算机网络系列篇

1、TCP/IP和UDP模型 TCP/IP分层&#xff08;4层&#xff09;&#xff1a;应用层&#xff0c;传输层&#xff0c;网络层&#xff0c;数据链路层 网络的七层架构 &#xff08;7层&#xff09;&#xff1a;应用层&#xff0c;表示层&#xff0c;会话层&#xff0c;传输层&#xff…

Spring事务的四大特性+事务的传播机制+隔离机制

Spring事务的四大特性 ① 原子性 atomicity 原子性是指事务是一个不可分割的工作单位&#xff0c;事务中的操作要么都发生&#xff0c;要么都不发生。 事务是一个原子操作, 由一系列动作组成。 组成一个事务的多个数据库操作是一个不可分割的原子单元&#xff0c;只有所有的…

无需任何三方库,在 Next.js 项目在线预览 PDF 文件

前言&#xff1a; 之前在使用Vue和其它框架的时候&#xff0c;预览 PDF 都是使用的 PDFObject 这个库&#xff0c;步骤是&#xff1a;下载依赖&#xff0c;然后手动封装一个 PDF 预览组件&#xff0c;这个组件接收本地或在线的pdf地址&#xff0c;然后在页面中使用组件的车时候…

【python】爬取百度热搜排行榜Top50+可视化【附源码】【送数据分析书籍】

英杰社区https://bbs.csdn.net/topics/617804998 一、导入必要的模块&#xff1a; 这篇博客将介绍如何使用Python编写一个爬虫程序&#xff0c;从斗鱼直播网站上获取图片信息并保存到本地。我们将使用requests模块发送HTTP请求和接收响应&#xff0c;以及os模块处理文件和目录操…

SpringBoot教程(七) | SpringBoot解决跨域问题

SpringBoot教程(七) | SpringBoot解决跨域问题 上篇文章我们介绍了SpringBoot的拦截器的写法&#xff0c;其中有一个比较重要的步骤&#xff0c;就是把我们写好的拦截器注册到Spring的一个配置类中&#xff0c;这个类是实现了WebMvcConfigurer 接口&#xff0c;这个类很重要&a…

如何十分钟快速看懂一篇NLP论文?

已经2024年了&#xff0c;该出现一个写论文解读AI Agent了。 大家肯定也在经常刷论文吧。 但真正尝试过用GPT去刷论文、写论文解读的小伙伴&#xff0c;一定深有体验——费劲。其他agents也没有能搞定的&#xff0c;今天我发现了一个超级厉害的写论文解读的agent &#xff0c…

flutter动态渲染从服务器请求的列表数据

比如我们从服务器请求到的列表数据&#xff0c;需要渲染到页面上&#xff0c;但是在flutter里面还是需要使用他们的ListView或者GridView或者别的组件才可以&#xff0c;或者有children这种属性的组件上使用。 比如我们在一个有状态的组件Lists里面&#xff0c;在initState的时…

导入失败,报错:“too many filtered rows xxx, “ErrorURL“:“

一、问题&#xff1a; 注&#xff1a;前面能正常写入&#xff0c;突然就报错&#xff0c;导入失败&#xff0c;报错&#xff1a;“too many filtered rows xxx, "ErrorURL":" {"TxnId":769494,"Label":"datax_doris_writer_bf176078-…

【大数据】Flink 详解(八):SQL 篇 Ⅰ

《Flink 详解》系列&#xff08;已完结&#xff09;&#xff0c;共包含以下 10 10 10 篇文章&#xff1a; 【大数据】Flink 详解&#xff08;一&#xff09;&#xff1a;基础篇【大数据】Flink 详解&#xff08;二&#xff09;&#xff1a;核心篇 Ⅰ【大数据】Flink 详解&…

C#/WPF 设置和启动Windows屏保程序

前言 我们平时电脑启动的屏保程序其本质也是应用程序&#xff0c;只是后缀名为.scr。所以我们只需要把应用程序后缀改为.scr&#xff0c;然后右键选择安装即可启动我们自己的屏保程序。 屏保注册表参数 设置电脑屏保参数&#xff0c;在个性化设置>锁屏界面>屏幕保护程序设…

SCA|可作为有效改进策略的算法——正余弦优化算法(Matlab/Python)

正余弦优化算法(Sine cosine algorithm&#xff0c;SCA)是由Mirjalili [1]在2016年提出&#xff0c;目前WOS上引用量2K&#xff0c;谷歌学术上4K。 不得不说Seyedali Mirjalili真是位大神级的人物(下图是Mirjalili开发的部分算法) SCA的核心思想是利用正、余弦函数波动的周期性…

Centos7 安装与卸载mysql

卸载 ps ajx | grep mysql &#xff1a; 查看当前服务器是否有mysql 没有的话就不需要卸载咯。 centos7 通过yum下载安装包通常是以.rpm为后缀&#xff0c;rpm -qa 可以查看当前服务器上所有的安装包&#xff1a; rpm -qa | grep mysql | xargs yum -y remove :将查询到的mysql…

网络安全中的“三高一弱”和“两高一弱”是什么?

大家在一些网络安全检查中&#xff0c;可能经常会遇到“三高一弱”这个说法。那么&#xff0c;三高一弱指的是什么呢&#xff1f; 三高&#xff1a;高危漏洞、高危端口、高风险外连 一弱&#xff1a;弱口令 一共是4个网络安全风险&#xff0c;其中的“高危漏洞、高危端口、弱…

华为设备vlan下配置MSTP,STP选举

核心代码,不同实例&#xff0c;承载不同流量&#xff0c;为每个实例设置一个根网桥达到分流的效果 stp region-config //进入stp区域的设置 region-name R1 //区域命名为R1 instance 1 vlan 10 …