Android开发自定义实现炫酷的进度条

news2024/11/26 7:48:00

本篇文章主要记录自定义View实现的水平进度条,包含的主要内容:水平进度条可设置渐变的颜色、在水平进度条上添加开始好结束的图片以及动态添加进度条下面的进度文字说明。下面是效果图展示:

实现的以上效果的主要代码分析说明:

第一步:绘制进度条进行初始化操作:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint bmpPaint = new Paint();
//将cacheBitmap绘制到该View组件
        if (cacheBitmap != null) {
            canvas.drawBitmap(cacheBitmap, 0, 0, bmpPaint);
        }
        view_edge_width = this.getWidth();
//        Log.e("打出来看看控件的宽度:", view_edge_width + "");
        init(progress,startprogress,starttime,endtime);
    }

第二步:主要绘制进度条的代码:

        /**
         * 画背景
       */
        RectF r = new RectF();
        r.left = 0;
        r.top = bitmapHeight;
        r.right = view_base_width;
        r.bottom = bitmapWidth + 10;
        cacheCanvas.drawRoundRect(r, 10f, 10f, backgroundPaint);

//绘制进度条的以及添加进度条中的图片和进度条下面的文字

 LinearGradient lg = new LinearGradient(0, 0, view_width, bitmapWidth, DEFAULT_START_COLOR, DEFAULT_END_COLOR, Shader.TileMode.CLAMP);
            progressPaint.setShader(lg);
            r.left = 0;
            r.top = bitmapHeight;
            r.right = view_width;
            r.bottom = bitmapWidth + 10;

//绘制进度条
            cacheCanvas.drawRoundRect(r, 10f, 10f, progressPaint);

//绘制进度条上面的图片
            cacheCanvas.drawBitmap(bitmap, view_width - bitmapWidth, bitmapHeight / 2, new Paint());

//添加进度条下面的文字
            cacheCanvas.drawText(endtime, view_width - bitmapWidth, bitmapHeight/2+90,textPaint);

第四步:下面贴上整个自定义View的全部代码:

/**
 * @author: GaoYaNan
 * @date: 2023/11/2
 * @content:
 */
public class ProgressSeek extends View {
    /**
     * 进度条的宽度
     */
    private int view_width;
    private int start_width;
    /**
     * 画布的宽度
     */
    private int view_base_width;
    /**
     * 控件的宽度
     */
    private int view_edge_width;
    /**
     * 进度
     */
    private int progress;
    private int startprogress;
    private String starttime;
    private String endtime;
    private Canvas cacheCanvas;
    /**
     * 背景颜色的画笔
     */
    private Paint backgroundPaint;
    /**
     * 进度条的画笔
     */
    private Paint progressPaint;
    /**
     *文字说明
     */
    private Paint textPaint;
    /**
     * 进度末端的图
     */
    private Bitmap bitmap;
    //开始进度图
    private Bitmap startbitmap;
    private int bitmapWidth;
    private int bitmapHeight;
    private Context context;
    //渐变色开始
    private static final int DEFAULT_START_COLOR = Color.parseColor("#F291C2");
    //渐变色结束
    private static final int DEFAULT_END_COLOR = Color.parseColor("#518CFF");
    /**
     * 缓存图片
     */
    private Bitmap cacheBitmap;
    public ProgressSeek(Context context) {
        super(context);
        initView(context);
    }
    public ProgressSeek(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }
    public ProgressSeek(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
    }
    private void initView(Context context) {
        this.context = context;
        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_progress_end);
        startbitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_progress_start);
        bitmapWidth =bitmap.getWidth();
        bitmapHeight = bitmap.getHeight()+DensityUtils.px2dip(context,60);
        backgroundPaint = new Paint();
        backgroundPaint.setStrokeWidth(bitmapHeight);
        backgroundPaint.setColor(Color.parseColor("#518CFF"));
        backgroundPaint.setAlpha(80);
        backgroundPaint.setDither(true);
        backgroundPaint.setAntiAlias(true);
        progressPaint = new Paint();
        progressPaint.setStrokeWidth(bitmapHeight);
        progressPaint.setDither(true);
        progressPaint.setAntiAlias(true);

        textPaint = new Paint();
        //绘制文字
       textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
       textPaint.setFakeBoldText(true);
       textPaint.setAntiAlias(true);
        textPaint.setTextSize(DensityUtils.px2dip(context,60));

       textPaint.setStrokeWidth(1f);
        textPaint.setColor(getResources().getColor(R.color.white));

        DisplayMetrics d = new DisplayMetrics();
        ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(d);
        view_base_width = d.widthPixels;
    }
    public void init(int progress,int startprogress,String starttime,String endtime) {
        this.progress = progress;
        this.startprogress = startprogress;
        this.starttime = starttime;
        this.endtime = endtime;
        if (view_width == 0) {//第一上来
            view_width = view_base_width * progress / 100;
        } else {
            if (startprogress>0){
                start_width = view_edge_width * startprogress / 100;
            }
            if (progress>0){
                view_width = view_edge_width * progress / 100;
            }

//
        }
        if (cacheBitmap != null) {
            if (!cacheBitmap.isRecycled()) {
                cacheBitmap.recycle();
                cacheBitmap = null;
            }
            cacheCanvas = null;
        }
        cacheBitmap = Bitmap.createBitmap(view_base_width, bitmapHeight * 2, Bitmap.Config.ARGB_8888);
        if (cacheCanvas == null) {
            cacheCanvas = new Canvas();
            cacheCanvas.setBitmap(cacheBitmap);
        }
/**
 * 画背景
 */
        RectF r = new RectF();
        r.left = 0;
        r.top = bitmapHeight;
        r.right = view_base_width;
        r.bottom = bitmapWidth + 10;
        cacheCanvas.drawRoundRect(r, 10f, 10f, backgroundPaint);


        if (progress > 0) {
            LinearGradient lg = new LinearGradient(0, 0, view_width, bitmapWidth, DEFAULT_START_COLOR, DEFAULT_END_COLOR, Shader.TileMode.CLAMP);
            progressPaint.setShader(lg);
            r.left = 0;
            r.top = bitmapHeight;
            r.right = view_width;
            r.bottom = bitmapWidth + 10;
            cacheCanvas.drawRoundRect(r, 10f, 10f, progressPaint);
            cacheCanvas.drawBitmap(bitmap, view_width - bitmapWidth, bitmapHeight / 2, new Paint());
            cacheCanvas.drawText(endtime, view_width - bitmapWidth, bitmapHeight/2+90,textPaint);
//            LogeUtils.e("timo-progress==:"+ progress + "");
        }
        if (startprogress ==0||startprogress >0) {
            LinearGradient lg = new LinearGradient(0, 0, start_width, bitmapWidth, DEFAULT_START_COLOR, DEFAULT_END_COLOR, Shader.TileMode.CLAMP);
            progressPaint.setShader(lg);
            RectF r1 = new RectF();
            r.left = 0;
            r.top = bitmapHeight;
            r.right = 0;
            r.bottom = bitmapWidth + 10;
            cacheCanvas.drawRoundRect(r, 10f, 10f, progressPaint);
            cacheCanvas.drawBitmap(startbitmap, 0, bitmapHeight / 2, new Paint());
            cacheCanvas.drawText(starttime, 0, bitmapHeight / 2+90, textPaint);
//            LogeUtils.e("timo-startprogress0==:"+ startprogress + "");
        }else if(startprogress <0){
            LinearGradient lg = new LinearGradient(0, 0, start_width, bitmapWidth, DEFAULT_START_COLOR, DEFAULT_END_COLOR, Shader.TileMode.CLAMP);
            progressPaint.setShader(lg);
            RectF r1 = new RectF();
            r.left = 0;
            r.top = bitmapHeight;
            r.right = 0;//
            r.bottom = bitmapWidth + 10;
            cacheCanvas.drawRoundRect(r, 10f, 10f, progressPaint);
            cacheCanvas.drawBitmap(startbitmap, start_width - bitmapWidth, bitmapHeight / 2, new Paint());
            cacheCanvas.drawText(starttime, 0, bitmapHeight / 2+80, textPaint);
//            cacheCanvas.drawText(starttime, start_width - bitmapWidth, bitmapHeight / 2+80, textPaint);
//            LogeUtils.e("timo-startprogress1==:"+ startprogress + "");
        }
        invalidate();
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint bmpPaint = new Paint();
//将cacheBitmap绘制到该View组件
        if (cacheBitmap != null) {
            canvas.drawBitmap(cacheBitmap, 0, 0, bmpPaint);
        }
        view_edge_width = this.getWidth();
//        Log.e("打出来看看控件的宽度:", view_edge_width + "");
        init(progress,startprogress,starttime,endtime);
    }
}

第五步:具体的使用说明:

在xml中添加上自定义View
<com.dz.common.view.ProgressSeek
    android:id="@+id/progressSeek"
    android:layout_width="match_parent"
    android:layout_height="100dp"/>

在使用的类中具体的用法:

//自定义渐变进度条
init中的参数具体的说明:依次是:结束进度、开始进度、开始进度文字说明、结束进度文字说明
progressSeek.init(60,10,"100%  开始","60%  结束");

以上就是本文的全部内容,仅供大家参考,如果问题可私信,如需转载请附上本文链接。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【开源】基于Vue和SpringBoot的电子元器件管理系统

项目编号&#xff1a; S 002 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S002&#xff0c;文末获取源码。} 项目编号&#xff1a;S002&#xff0c;文末获取源码。 目录 一、摘要1.1 项目简介1.2 项目录屏 二、研究内容三、界面展示3.1 登录&注册&主页…

一个基于百度飞桨封装的.NET版本OCR工具类库 - PaddleOCRSharp

前言 大家有使用过.NET开发过OCR工具吗&#xff1f;今天给大家推荐一个基于百度飞桨封装的.NET版本OCR工具类库&#xff1a;PaddleOCRSharp。 OCR工具有什么用&#xff1f; OCR&#xff08;Optical Character Recognition&#xff09;工具可以将图像或扫描文件中的文本内容转…

“找不到emp.dll,无法继续执行代码”的问题要如何修复

今天我想和大家分享的是关于emp.dll缺失的4种解决方法。首先&#xff0c;让我们来了解一下emp.dll缺失的原因以及它是什么文件。 emp.dll是一个动态链接库文件&#xff0c;它位于系统的安装目录下。它是Windows操作系统的一部分&#xff0c;用于支持某些应用程序的正常运行。当…

Python批量导入及导出项目中所安装的类库包到.txt文件(补充)

Python批量导入及导出项目中所安装的类库包到.txt文件 生成requirements文件 建议使用&#xff0c;该方式形成文档最简洁&#xff1a; pip list --formatfreeze > requirements.txt

js树形数组遍历练习,扁平化、格式化、获取节点父级

1.树形数组扁平化 数组扁平化的方式很多&#xff0c;这里主要是用递归处理&#xff0c;除此之外还有正则、扩展运算符等等 const list [{name:1,id:1,children:[{name:11,id:11,children:[{name:111,id:111}]},{name:12},]},{name:2,id:2,children:[{name:21,id:21,children:…

【Redis】set常用命令集合间操作内部编码使用场景

文章目录 前置知识常见命令SADDSMEMBERSSISMEMBERSCARDSPOPSMOVESREM 集合间操作SINTERSINTERSTORESUNIONSUNIONSTORESDIFFSDIFFSTORE 命令小结内部编码测试内部编码 使用场景 前置知识 集合类型也是保存多个字符串类型的元素的&#xff0c;但和列表类型不同的是&#xff0c;在…

目标检测回归损失函数(看情况补...)

文章目录 L1 loss-平均绝对误差(Mean Absolute Error——MAE)L2 loss-均方误差(Mean Square Error——MSE)Smooth L1 LossMAE、MSE、Smooth L1对比IoU LossGIoU LossDIoU Loss、CIoU LossE-IoU Loss、Focal E-IoU LossReferenceL1 loss-平均绝对误差(Mean Absolute Error——…

kubernetes helm

一、helm Helm是Kubernetes 应用的包管理工具&#xff0c;主要用来管理 Charts&#xff0c;类似Linux系统的yum。Helm Chart 是用来封装 Kubernetes 原生应用程序的一系列 YAML 文件。可以在你部署应用的时候自定义应用程序的一些 Metadata&#xff0c;以便于应用程序的分发。…

Python算法例9 罗马数字转换为整数

1. 问题描述 给定一个罗马数字&#xff0c;将其转换为整数&#xff0c;要求返回结果的取值为1~3999。 2. 问题示例 Ⅳ→4&#xff0c;Ⅻ→12&#xff0c;ⅩⅪ→21&#xff0c;XCVI→99。 3. 代码实现 def roman_to_int(s):roman_map {I: 1, V: 5, X: 10, L: 50, C: 100, …

软件测试/校招推荐丨鼎捷软件股份有限公司岗位开放

点此获取更多相关资料 软件测试工程师 岗位职责 负责公司产品的日常测试工作&#xff1b;依据软件需求和非功能需求&#xff0c;编写测试方案和测试用例&#xff0c;设计测试脚本&#xff1b;负责服务器系统和软件的日常维护工作&#xff0c;为上线部署和运维活动提供技术支持…

Yakit工具篇:WebFuzzer模块之序列操作

简介 Web Fuzzer 序列就是将多个 Web Fuzzer 节点串联起来&#xff0c;实现更复杂的逻辑与功能。例如我们需要先进行登录&#xff0c;然后再进行其他操作&#xff0c;这时候我们就可以使用 Web Fuzzer 序列功能。或者是我们在一次渗透测试中需要好几个步骤才能验证是否有漏洞这…

VMWare中的Centos7,DHCP获取不到IP地址

Centos是通过桥接的方式连接到主机&#xff0c; 某次开机后&#xff0c;Centos中获取不到&#xff29;&#xff30;地址&#xff0c;可以先卸载主机中的VMware Bridge Protocal. 然后在VMWare中的虚拟网络编辑器中&#xff0c;还原默认设置。 重新开关centos中的网络就可以了。…

【Unity】零基础实现塔防游戏中敌人沿固定路径移动的功能

目录 场景搭建 烘焙(Bake) 敌人动作控制 脚本实现 我们知道&#xff0c;在一些塔防小游戏中&#xff0c;敌人往往会沿着给定的一条路径移动&#xff0c;我们在条路的路边会布置防御设施&#xff0c;攻击消灭敌人&#xff0c;阻止敌人到达终点。 场景搭建 我们首先新建一个…

【python海洋专题四十三】海洋指数画法--多色渐变柱状图

【python海洋专题四十三】海洋指数画法–多色渐变柱状图 图片 往期推荐 图片 【python海洋专题一】查看数据nc文件的属性并输出属性到txt文件 【python海洋专题二】读取水深nc文件并水深地形图 【python海洋专题三】图像修饰之画布和坐标轴 【Python海洋专题四】之水深…

电动自行车一车一码管理系统

一、应用介绍 针对电动车乱停乱放问题&#xff0c;通过对电动车赋码实现电动车基本信息管理、日常维护登记管理。日常巡查过程中&#xff0c;发现乱停乱放&#xff0c;微信扫码即可查看车主信息&#xff0c;可以及时播打电话通知车主&#xff0c;同时微信扫码及时登记车辆违规信…

临界资源,临界区,通信的干扰问题(互斥),信号量(本质,上下文切换问题,原子性,自身的安全性,操作)

目录 引入 概念 临界资源 临界区 干扰存在原因 互斥 信号量 引入 举例 概念 介绍 表示可用资源数 表示等待进程数 申请信号量 信号量的本质 全局变量? 共享内存? 不安全问题 -- 上下文切换 原子性 信号量自身的安全性 原子操作的意义 操作 引入 通信…

【算法练习Day42】买卖股票的最佳时机 III买卖股票的最佳时机 IV

​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;练题 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录 买卖股票的最佳时机 III买卖…

详解FreeRTOS:系统时钟节拍(进阶篇—8)

在详解FreeRTOS:FreeRTOS时间片调度(进阶篇—7)中我们讲到了时钟节拍这个概念,本篇博文将详细讲解FreeRTOS系统时钟节拍相关知识。 不管是什么系统,运行都需要有个系统时钟节拍,xTickCount 就是FreeRTOS 的系统时钟节拍计数器。每个滴答定时器中断中 xTickCount 就会加一…

第七讲:利用类事件改变对象的属性(上)

《VBA中类的解读及应用》教程【10165646】是我推出的第五套教程&#xff0c;目前已经是第一版修订了。这套教程定位于最高级&#xff0c;是学完初级&#xff0c;中级后的教程。 类&#xff0c;是非常抽象的&#xff0c;更具研究的价值。随着我们学习、应用VBA的深入&#xff0…

数据结构-栈和队列(一)

目录 1.栈 1.1 栈的概念及结构 1.2 栈的实现 初始化栈&#xff1a; 入栈&#xff1a; 判空函数&#xff1a; 出栈&#xff1a; 获取栈顶元素&#xff1a; 获取栈中有效元素的个数&#xff1a; 销毁栈&#xff1a; 完整代码&#xff1a; 测试&#xff1a; 2. 队列 …