Android 自定义View圆形进度条

Android自定义View——从零开始实现圆形进度条 以前老是用别人造的轮子,知其然不知其所以然,有时看懂了别人写的过多几个月又忘了,遂来开个坑把一步步实现和思路写下来,弄成一个系列。本篇只要讲的是Android自定义圆形进度条 阅读详情

效果
1.创建自定义属性文件:在values下面创建attrs.xml属性文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="XCRoundProgressBar">
    <attr name="roundColor" format="color"/>
    <attr name="roundProgressColor" format="color"/>
    <attr name="roundWidth" format="dimension"></attr>
    <attr name="innerRoundColor" format="color" />
    <attr name="textColor" format="color" />
    <attr name="textSize" format="dimension" />
    <attr name="max" format="integer"></attr>
    <attr name="textIsDisplayable" format="boolean"></attr>
    <attr name="style">
        <enum name="STROKE" value="1"></enum>
        <enum name="FILL" value="1"></enum>
    </attr>
</declare-styleable>

</resources>
  1. 实现自定义View类:
package com.xc.xcskin.view;

import com.xc.xcskin.R;
import com.xc.xcskin.R.styleable;

import android.R.integer;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.View;

/**
 * 带进度百分比显示的进度条,线程安全的View,可直接在线程中更新进度
 * @author zhaozhiwei
 *
 */
public class XCRoundProgressBar extends View{

    
    
    private Paint paint;//画笔对象的引用
    private int roundColor;//圆环的颜色
    private int roundProgressColor;//圆环进度的颜色
    private int innerRoundColor;//圆环内部圆颜色
    private float roundWidth;//圆环的宽度
    private int textColor;//中间进度百分比字符串的颜色
    private float textSize ;//中间进度百分比字符串的字体
    private int max;//最大进度
    private int progress;//当前进度
    private boolean isDisplayText;//是否显示中间百分比进度字符串
    private int style;//进度条的风格:空心圆环或者实心圆环
    private static final int STROKE = 0;//空心
    private static final int FILL = 1;//实心
    
    public XCRoundProgressBar(Context context){
        this(context, null);
    }
    public XCRoundProgressBar(Context context,AttributeSet attrs){
        this(context,attrs,0);
    }
    public XCRoundProgressBar(Context context, AttributeSet attrs,
            int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // TODO Auto-generated constructor stub
        
        paint  =  new Paint();
        //从attrs.xml中获取自定义属性和默认值
        TypedArray typedArray  = context.obtainStyledAttributes(attrs, R.styleable.XCRoundProgressBar);
        roundColor = typedArray.getColor(R.styleable.XCRoundProgressBar_roundColor, Color.GREEN);
        roundProgressColor = typedArray.getColor(R.styleable.XCRoundProgressBar_roundProgressColor, Color.RED);
        innerRoundColor = typedArray.getColor(R.styleable.XCRoundProgressBar_innerRoundColor, Color.GRAY);
        roundWidth = typedArray.getDimension(R.styleable.XCRoundProgressBar_roundWidth, 5);
        textColor  =typedArray.getColor(R.styleable.XCRoundProgressBar_textColor, Color.RED);
        textSize = typedArray.getDimension(R.styleable.XCRoundProgressBar_textSize, 15);
        max = typedArray.getInteger(R.styleable.XCRoundProgressBar_max, 100);
        style = typedArray.getInt(R.styleable.XCRoundProgressBar_style, STROKE);
        isDisplayText  =typedArray.getBoolean(R.styleable.XCRoundProgressBar_textIsDisplayable, true);
        typedArray.recycle();
        
    }
    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);
        
        //画最外层大圆环
        int centerX = getWidth()/2;//获取中心点X坐标
        int certerY = getHeight()/2;//获取中心点Y坐标
        int radius =(int)(centerX - roundWidth/2);//圆环的半径
        paint.setColor(roundColor);
        paint.setStyle(Paint.Style.STROKE);//设置空心
        paint.setStrokeWidth(roundWidth);//设置圆环宽度
        paint.setAntiAlias(true);//消除锯齿
        canvas.drawCircle(centerX,certerY, radius, paint);//绘制圆环
        
        //绘制圆环内部圆
        paint.setColor(innerRoundColor);
        paint.setStyle(Paint.Style.FILL);
        paint.setAntiAlias(true);
        canvas.drawCircle(centerX, certerY, radius-roundWidth/2, paint);
        
        
        
        //画进度
        paint.setStrokeWidth(roundWidth);//设置圆环宽度
        paint.setColor(roundProgressColor);//设置进度颜色
        RectF oval = new RectF(centerX - radius, centerX - radius, centerX 
                + radius, centerX + radius);  //用于定义的圆弧的形状和大小的界限 
        switch (style) {
        case STROKE: {
            paint.setStyle(Paint.Style.STROKE);
            canvas.drawArc(oval, 0, 360 * progress / max, false, paint); // 根据进度画圆弧
            break;
        }
        case FILL: {
            paint.setStyle(Paint.Style.FILL);
            if (progress != 0)
                canvas.drawArc(oval, 0, 360 * progress / max, true, paint); // 根据进度画圆弧
            break;
        }
        }
        //画中间进度百分比字符串
        paint.setStrokeWidth(0);
        paint.setColor(textColor);
        paint.setTextSize(textSize);
        paint.setTypeface(Typeface.DEFAULT_BOLD);
        int percent = (int)(((float)progress / (float)max) * 100);//计算百分比 
        float textWidth = paint.measureText(percent +"%");//测量字体宽度,需要居中显示
        
        if(isDisplayText && style == STROKE && percent != 0){
            canvas.drawText(percent+"%", centerX-textWidth/2, centerX + textSize/2, paint);
        }
        
        
    }
    public Paint getPaint() {
        return paint;
    }
    public void setPaint(Paint paint) {
        this.paint = paint;
    }
    public int getRoundColor() {
        return roundColor;
    }
    public void setRoundColor(int roundColor) {
        this.roundColor = roundColor;
    }
    public int getRoundProgressColor() {
        return roundProgressColor;
    }
    public void setRoundProgressColor(int roundProgressColor) {
        this.roundProgressColor = roundProgressColor;
    }
    public float getRoundWidth() {
        return roundWidth;
    }
    public void setRoundWidth(float roundWidth) {
        this.roundWidth = roundWidth;
    }
    public int getTextColor() {
        return textColor;
    }
    public void setTextColor(int textColor) {
        this.textColor = textColor;
    }
    public float getTextSize() {
        return textSize;
    }
    public void setTextSize(float textSize) {
        this.textSize = textSize;
    }
    public synchronized int getMax() {
        return max;
    }
    public synchronized void setMax(int max) {
        if(max < 0){
            throw new IllegalArgumentException("max must more than 0");
        }
        this.max = max;
    }
    public synchronized int getProgress() {
        return progress;
    }
    /**
     * 设置进度,此为线程安全控件,由于考虑多线的问题,需要同步
     * 刷新界面调用postInvalidate()能在非UI线程刷新
     * @author caizhiming
     */ 
    public synchronized void setProgress(int progress) {
        if(progress < 0){
            throw new IllegalArgumentException("progress must more than 0");
        }
        if(progress > max){
            this.progress = progress;
        }
        if(progress <= max){
            this.progress = progress;
            postInvalidate();
        }
    }
    public boolean isDisplayText() {
        return isDisplayText;
    }
    public void setDisplayText(boolean isDisplayText) {
        this.isDisplayText = isDisplayText;
    }
    public int getStyle() {
        return style;
    }
    public void setStyle(int style) {
        this.style = style;
    }

    
}

3.使用//我这里抽基了Activity,你们测试时候记得在布局中使用,必须设置宽高,找到ID 设置属性。不然没效果哦

public class MainActivity extends BaseActivity{


    private  int num =0;
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case 1:
                    num++;
                    Log.i("AAAA", "handleMessage: "+num);
                    if (num!=100){
                        Message message = handler.obtainMessage(1);
                        handler.sendMessageDelayed(message,200);
                        Progress.setProgress(num+1);//设置已进度
                    }else if (num==100){
                        num = 0;
                        Message message = handler.obtainMessage(1);
                        handler.sendMessageDelayed(message,200);
                    }
            }
            super.handleMessage(msg);
        }
    };


    @Override
    protected void initData() {

        Message message = handler.obtainMessage(1);
        handler.sendMessageDelayed(message,200);


            Progress.setMax(100);//最大值
            Progress.setTextSize(50);//中间数字大小
            Progress.setRoundWidth(40);//画笔宽度
            Progress.setDisplayText(true);//是否显示中间进度百分比
  
    }

原博客自定义进度条

实现圆形进度条:Android自定义View高级示例 自定义View是Android开发中提升用户界面丰富性的关键技术之一。从基础的概念到复杂的动画实现,自定义View都能有效地满足开发者的各种需求。想要成功创建一个自定义View,开发者必须遵循几个核心步骤。首先,必须了解Android的绘图系统,特别是Canvas和Paint类的使用。接着,需要掌握onMeasure和onDraw等方法来测量和绘制内容。此外,自定义View时还需要处理好布局参数的设置,确保View在各种布局环境下都能正确显示。 阅读详情

相关推荐

Android自定义View进阶:创建带进度圆形进度条

自定义View是Android开发中不可或缺的高级技能,它赋予了开发者对界面的完全掌控,让我们可以创造出独特且符合特定需求的UI组件。要深入理解并熟练运用自定义View,不仅需要对Android绘图体系有清晰的认识,还要掌握自定义属性、事件处理、动画集成等关键点。本章将会带您走进Android自定义View的高级世界,帮助您从理论到实践,逐步构建出强大的自定义View组件。我们将从创建一个简单的自定义View开始,逐步深入了解并实现复杂的交互和动画效果。

weixin_31163455的博客 1125

Android自定义View之画圆环(进阶篇:圆形进度条)

前言: &amp;amp;amp;amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;amp;amp;amp;nbsp;如果你想读懂或者更好的理解本篇文章关于自定义圆环或圆弧的内容.请你务必提前阅读下Android自定义View之画圆环(手把手教你如何一步步画圆环).在这篇文章中,详细描述了最基本的自定义圆环的绘

君羊 1万+

Android自定义View:实现可拖动圆形进度条

自定义View是Android开发中一个非常重要的概念,它赋予了开发者强大的能力来创建独特且具有高度定制性的用户界面元素。通过继承已有的View类,开发者可以实现新的功能,并在应用中提供一致的用户体验。在自定义View的开发过程中,功能性扩展和自定义属性的设计是至关重要的。它们不仅提高了View的灵活性和可重用性,还增强了用户的体验。本章将深入探讨自定义属性的意义和实现方法,并展示如何扩展进度条的功能。

weixin_42581846的博客 813

Android 自定义view圆形进度条

自定义view-圆形进度条,效果图如下。上代码,里面有详细注释。

csdndfg2的博客 366

解决用加速器以后,电脑无法连接网络的问题

相信很多朋友也遇到过,用加速器以后,电脑网络直接断了,或者访问外网时打不开的情况解决办法是。

qq_46368050的博客 1万+

Android 性能之 Game Mode

本文的目的是介绍 AOSP Game Mode 功能。Game Mode 功能的核心是系统服务 GameManagerService,在本文中用 GMS 指代 GameManagerService。在 API 26 之后,应用开发者可以通过将应用的 category 属性设置为 "game",使系统(即 GMS)能够将该应用识别为 "游戏"。GMS 定义了 4 种 game mode,即 1|2|3|4|standard|performance|battery|custom;

专注于系统快稳省领域 3064

Android 自定义View之圆形进度条

需求是不停的,会有这些需求:可指定画笔(宽度、颜色等)、可指定动画时长等。这些可以通过创建 Java 接口来设置,但我要学自定义View,就要用attr。未完待续~~Android Canvas的drawText()和文字居中方案。

weixin_44021334的博客 6223

CAD二次开发(C#版):从零搭建开发环境与核心DLL引用指南

本文详细介绍了使用C#进行CAD二次开发的环境搭建与核心DLL引用指南,涵盖Visual Studio配置、AutoCAD插件项目创建、DLL引用技巧及调试方法。通过实战示例和常见问题排查,帮助开发者快速掌握CAD二次开发的核心技术,提升开发效率。

weixin_28837817的博客 728

Android:自定义View实现绚丽的圆形进度条

Android:自定义View实现绚丽的圆形进度条

books1958的专栏 8706

STM32学习笔记【江科协】【4-2】OLED显示屏

可以注意到接电源的GND和VCC同时和PB6、PB7号口连接,我们可以直接不初始化这两个引脚解决,因为STM32的引脚上电后,如果不初始化,默认是浮空输入的模式,在这个模式下,引脚不会输出电平,所以不会有什么影响,或者直接给PB6口输出低电平,PB7口输出高电平,用GPIO口直接给OLED供电,这个也是没问题的,因为OLED的功率很小这个也是可以驱动的,不过用GPIO口供电不是很规范,实际项目还是用电源供电。然后点击这里放大镜里面带d的图标,进入调试模式,这个界面里,

m0_74651303的博客 1595

保姆级教程:在Ubuntu 21.04上搞定USRP X410的UHD 4.1驱动与Gnuradio 3.9安装(含虚拟机网络避坑指南)

本文提供在Ubuntu 21.04上配置USRP X410的UHD 4.1驱动与Gnuradio 3.9的详细教程,涵盖虚拟机网络设置、依赖安装、源码编译及常见问题解决方案,帮助开发者高效搭建SDR开发环境。

weixin_27869497的博客 272

简单的进度条圆形

转载 https://blog.youkuaiyun.com/qq_32519693/article/details/76726525 package com.cjqc.myindicator.view; /** * Created by hrd on 2018/9/20. */ import android.content.Context; import android.content.res.T...

Hao、 413

新手避坑指南:在MacBook上为PyTorch正确配置MPS环境,跑通第一个YOLOv8训练

本文详细指导新手如何在MacBook上为PyTorch正确配置MPS环境,并成功运行YOLOv8训练。从环境准备、PyTorch安装到YOLOv8配置和性能调优,提供全面的避坑指南和实用技巧,帮助开发者充分利用Mac的GPU加速能力。

weixin_29100399的博客 228

Android自定义View之圆形进度条

Android自定义View之圆形进度条尽管github上的开源圆形进度条已经很多了,但是我仍然希望能通过自己完成一个,接下来我就一步一步实现圆形进度条,今天我们要实现的效果图如下: 观察上面两幅图我们可以看到,这个图形是由两部分组成的中间的圆形+外围的弧形,我们自然而然的想到了用canvas画。想好就开始实践, 新建PercentDigitalView项目,新建view包,新建Perc

小海编码日记 676

元数据治理实战:构建企业数据地图与血缘体系

元数据(Metadata)是描述数据的数据,是你能了解“数据是怎么来的”、“它是做什么的”、“能不能用”的基础信息。📌 举个例子:order_idstringods_order定义:平台内用户在订单系统中产生的唯一订单编号更新时间:每天凌晨 2 点,由 Airflow 调度任务生成所属人:张三(数据开发部)🔍 这些信息本身不直接参与计算,但它们是数据可管理、可追踪、可评估的基础。模块实战建议元数据类型技术 + 业务 + 操作元数据三类统一治理治理路径。

晴天彩虹雨的博客 290

【异常】OpenClaw 飞书端 OpenClaw: access not configured. Pairing code: [] Ask the bot owner to approve with

摘要: OpenClaw飞书机器人交互中出现的access not configured报错,是因用户或组织未配置访问权限触发的拦截提示。报错包含组织单元ID和配对校验码,需管理员审批开通权限。普通用户需提交完整报错信息给管理员处理;管理员可通过执行标准化命令单次审批,或批量配置组织白名单优化权限管理。建议提前梳理权限范围、及时同步组织架构变更,并定期审计权限列表以确保安全合规。

奶爸的编程之路,也就一周冷个三天 371

Android 自定义View实现圆形加载进度条

Android 自定义view圆形加载进度条

Android_Gt 3476

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Android自定义view实现圆形进度条更新

Android自定义view实现圆形进度条更新准备期实现自定义ViewService主Activitylayout布局最终实现效果 刚回顾完群英传的自定义view章节,在3.6.3.1中弧形展示图,看完在想,做成加载进度条是否稍微有趣点呢,就着手开始实现了。先看下弧形展示图。 准备期 有了需求,那么就得先思考如何实现,开启线程,自加后更新数据?还是开个服务再返回更新呢?我选择后者,作为小白,多拓...

J1036767889的博客 484

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Android自定义view实现圆形进度条

Android自定义view实现圆形进度条

吐尔洪江 2530

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

android绘制环形进度_Android 自定义 View 之圆形进度条总结

原标题:Android 自定义 View 之圆形进度条总结最近撸了一个圆形进度条的开源项目,算是第一次完完整整的使用自定义 View 。在此对项目开发思路做个小结,欢迎大家 Star 和 Fork该项目总共实现了三种圆形进度条效果CircleProgress:圆形进度条,可以实现仿 QQ 健康计步器的效果,支持配置进度条背景色、宽度、起始角度,支持进度条渐变DialProgress:类似 Circ...

weixin_39888412的博客 417

Android进度条阴影,Android自定义View之圆形进度条总结

最近撸了一个圆形进度条的开源项目,算是***次完完整整的使用自定义 View 。在此对项目开发思路做个小结,欢迎大家 Star 和 Fork。该项目总共实现了三种圆形进度条效果CircleProgress:圆形进度条,可以实现仿 QQ 健康计步器的效果,支持配置进度条背景色、宽度、起始角度,支持进度条渐变DialProgress:类似 CircleProgress,但是支持刻度WaveProgre...

weixin_39642619的博客 506

Android自定义View-圆形进度条

好几天不写博客了,这段时间一直没时间,感觉一直在忙,但是进度不大。 好了,言归正传,最近项目里要用到这么一个自定义view,是一个圆形的进度圆环,现在学习下怎么来自定义它。 源码下载地址https://github.com/baojie0327/ViewAndGroup自定义之前先分析一下,这个自定义View主要有以下几个部分组成: - 最外层的圆环 - 圆环上的小圆点,会随着进度移动 -

香蕉你个不呐呐的博客 581

Android自定义View之圆形比例图(进度条)

在我们APP中,经常会用到如下的一张比例图:                                                      这个比例图可以清楚的展示一个项目所占的比例,同时也可以变成一个圆形进度条:

isJoker的博客 1834

安卓进阶之路:自定义View圆形进度条源码解析

安卓进阶之路:自定义View圆形进度条源码解析 去发现同类优质开源项目:https://gitcode.com/ 项目介绍 在Android开发中,自定义View是区分普通开发者与高手的重要技能之一。今天,我们介绍的开源项目——自定义View,自定义属性(带进度的圆形进度条)源码,是一个非常适合进阶学习的资源。该源码提供了一种新颖的进度展示方式,让应用界面更加直观和美观。 项目技术分析 项目基于A...

gitblog_06724的博客 270

android自定义view之半圆形进度条

安卓自定义VIEW之半圆进度条

baidu_34934230的博客 3157
上一篇: Android仿微信上传图片发朋友圈
下一篇: Android 默认隐藏键盘的自动弹出
Android_Mr_Zhao
博客等级 码龄8年 9粉丝 83原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值