自定义view - 炫酷进度条

news2024/10/7 2:26:29

1. 思路分析

自定义View步骤:
1>:values__attrs.xml,自定义属性;
2>:在第三个构造方法中,获取自定义属性;
3>:onMeasure:不是非必须的,测量控件大小;
4>:onDraw:所有绘制代码都写在onDraw方法中;

思路分析
1>:自定义属性:内圆颜色、外圆颜色、圆弧宽度、中间文字颜色、文字大小;
2>:自定义ProgressBar,继承View;

2. 效果图如下

在这里插入图片描述

3. 代码如下

1>:attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="ProgressBar">
        <attr name="innerBackground" format="color"/>
        <attr name="outterBackground" format="color"/>
        <attr name="roundWidth" format="dimension"/>
        <attr name="progressTextSize" format="dimension"/>
        <attr name="progressTextColor" format="color"/>
    </declare-styleable>
</resources>

2>:ProgressBar

package com.example.view05_day;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;

import androidx.annotation.Nullable;

public class ProgressBar extends View {
    private int innerColor = Color.BLACK;
    private int outColor = Color.RED;
    private int mTextSize = 15;
    private int mTextColor = Color.BLACK;
    private int mRoundWidth = 20;
    private int currentProgress = 50;
    private int maxNum = 100;

    private Paint innerPaint, outerPaint, mPaintText;

    public ProgressBar(Context context) {
        this(context, null);
    }

    public ProgressBar(Context context, @Nullable @org.jetbrains.annotations.Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ProgressBar(Context context, @Nullable @org.jetbrains.annotations.Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ProgressBar);
        innerColor = array.getColor(R.styleable.ProgressBar_innerBackground, innerColor);
        outColor = array.getColor(R.styleable.ProgressBar_outterBackground, outColor);
        mTextSize = array.getDimensionPixelSize(R.styleable.ProgressBar_progressTextSize,sp2px(mTextSize));
        mRoundWidth = (int)array.getDimension(R.styleable.ProgressBar_roundWidth, dip2px(mRoundWidth));
        mTextColor = array.getColor(R.styleable.ProgressBar_progressTextColor, mTextColor);
        array.recycle();

        innerPaint = new Paint();
        innerPaint.setAntiAlias(true);
        innerPaint.setColor(innerColor);
        innerPaint.setStrokeWidth(mRoundWidth);
        innerPaint.setStyle(Paint.Style.STROKE);

        outerPaint = new Paint();
        outerPaint.setAntiAlias(true);
        outerPaint.setColor(outColor);
        outerPaint.setStrokeWidth(mRoundWidth);
        outerPaint.setStyle(Paint.Style.STROKE);

        mPaintText = new Paint();
        mPaintText.setAntiAlias(true);
        mPaintText.setColor(mTextColor);
        mPaintText.setTextSize(mTextSize);
    }

    private int sp2px(int sp) {
        return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, getResources().getDisplayMetrics());
    }

    private int dip2px(int dip) {
        return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, getResources().getDisplayMetrics());
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //只保证正方形
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(Math.min(width, height), Math.min(width, height));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //先画内圆
        int center = getWidth()/2;
        int radius = center - mRoundWidth/2;
        canvas.drawCircle(center,center,radius,innerPaint);

        //再画外圆,画圆弧
        RectF rectF = new RectF(0+mRoundWidth/2,0+mRoundWidth/2,getWidth()-mRoundWidth/2,getHeight()-mRoundWidth/2);
        if (currentProgress == 0) {
            return;
        }
        float percent = (float)currentProgress/maxNum;
        canvas.drawArc(rectF,0, 360 * percent, false, outerPaint);

        //画进度文字
        String text = ((int)(percent * 100)) + "%";
        Rect bounds = new Rect();
        mPaintText.getTextBounds(text,0,text.length(),bounds);
        int x = getWidth()/2 - bounds.width()/2;
        Paint.FontMetrics fontMetrics = mPaintText.getFontMetrics();
        int dy = (int)((fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom);
        int baseline = getHeight()/2 + dy;
        canvas.drawText(text,x,baseline,mPaintText);
    }

    //给几个方法
    public synchronized void setMax (int max) throws IllegalArgumentException{
        if (max < 0) {
            throw new IllegalArgumentException("FUCK YOU");
        }
        this.maxNum = max;
    }

    public synchronized void setProgress (int progress) throws IllegalArgumentException{
        if (progress < 0) {
            throw new IllegalArgumentException("progress error");
        }
        this.currentProgress = progress;
        invalidate();
    }
}

3>activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingTop="16dp"
    tools:context=".MainActivity">

    <com.example.view05_day.ProgressBar
        android:id="@+id/ProgressBar"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:progressTextColor="@color/teal_700"
        app:innerBackground= "@color/black"
        app:outterBackground="@color/purple_200"
        app:progressTextSize="20dp"
        app:roundWidth = "20dp"/>
</RelativeLayout>

4>:MainActivity.java

package com.example.view05_day;

import androidx.appcompat.app.AppCompatActivity;

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

public class MainActivity extends AppCompatActivity {
    private ShapeView mShapeView;
    private static final String TAG = "wqq";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ProgressBar mProgressBar = findViewById(R.id.ProgressBar);
        mShapeView = findViewById(R.id.shapView);
        try {
            mProgressBar.setMax(4000);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        }
        ValueAnimator animator = ObjectAnimator.ofFloat(0,4000);
        animator.setDuration(2000);
        animator.start();
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float progress = (float)animation.getAnimatedValue();
                try {
                    mProgressBar.setProgress((int)progress);
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public void exchange(View view)
    {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    mShapeView.exchange();
                    Log.e(TAG, "run: wqq");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
}

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

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

相关文章

基于SSM的简易图书管理系统

基于SSM的简易图书管理系统说明书 目录 1.系统设计... 1 1.1背景意义... 1 1.2创新性... 1 1.3功能介绍... 1 1.4应用价值... 1 2.系统启动与使用... 2 2.1下载系统压缩包并解压... 2 2.2打开系统文件夹... 3 2.3 SSM必需maven依赖加载和tomcat配置... 4 2.4启动系统... 5 2.5进…

SSM游戏社交网站【纯干货分享,免费领源码05667】

目 录 摘要 1 绪论 1.1 研究意义 1.2研究方法 1.3ssm框架 1.4论文结构与章节安排 2 2 游戏社交网站系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3数据删除流程 2.3 系统功能分析 2.3.1功能性分析 2.3.2非功能性分析 2…

采集设置为固定值或随机值

网站采集软件怎么采集设置为固定值或随机值&#xff1f; 1. 设置为固定值 例如在简数采集器&#xff0c;进入对应的详情提取器字段数据处理&#xff0c;xpath值为空&#xff0c;然后空内容缺省值设置为固定值&#xff0c;例如示例图的填写为最新资讯&#xff0c;保存完成。 2.…

关于使用easyExcel读取前端文件和MybatisPlus批量插入

关于使用easyExceld读取前端文件和MybatisPlus批量插入 文章目录 关于使用easyExceld读取前端文件和MybatisPlus批量插入实体类监听器开始调用可能出现的问题最后&#xff0c;关于MybatisPlus的批量插入写一个工具类写一个配置类到Mappe中添加这个方法 最近写项目&#xff0c;后…

SUSE 宣布开发与 RHEL 兼容的 Linux 发行版

导读近日消息&#xff0c;SUSE 在今天宣布&#xff0c;它将 fork 公开可用的 Red Hat Enterprise Linux (RHEL)&#xff0c;并将开发和维护与 RHEL 兼容的发行版&#xff0c;所有人都可以不受限制地使用该发行版本。未来几年&#xff0c;SUSE 计划向该项目投资超过 1000 万美元…

分布式训练数据并行极致优化:ZeRO

分布式训练数据并行极致优化&#xff1a;ZeRO 导言 随着 ChatGPT 的爆火&#xff0c;大模型成为了近些年人工智能的研究热点。大模型能力惊艳&#xff0c;但是训练起来成本也不小。大模型&#xff0c;顾名思义&#xff0c;最大的特点就是 “大”。这里的 “大” 通常指的就是…

本地部署 Stable Diffusion XL 1.0 Gradio Demo WebUI

StableDiffusion XL 1.0 Gradio Demo WebUI 0. 先展示几张 StableDiffusion XL 生成的图片1. 什么是 Stable Diffusion XL Gradio Demo WebUI2. Github 地址3. 安装 Miniconda34. 创建虚拟环境5. 安装 Stable Diffusion XL Gradio Demo WebUI6. 启动 Stable Diffusion XL Gradi…

c语言内存函数的深度解析

本章对 memcpy&#xff0c;memmove&#xff0c;memcmp 三个函数进行详解和模拟实现&#xff1b; 本章重点&#xff1a;3个常见内存函数的使用方法及注意事项并学会模拟实现&#xff1b; 如果您觉得文章不错&#xff0c;期待你的一键三连哦&#xff0c;你的鼓励是我创作的动力…

基于深度学习的裂纹图像分类研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

2023最新ChatGPT商业运营版网站源码+支持ChatGPT4.0+GPT联网+支持ai绘画(Midjourney)+支持Mind思维导图生成

本系统使用Nestjs和Vue3框架技术&#xff0c;持续集成AI能力到本系统&#xff01; 支持GPT3模型、GPT4模型Midjourney专业绘画&#xff08;全自定义调参&#xff09;、Midjourney以图生图、Dall-E2绘画Mind思维导图生成应用工作台&#xff08;Prompt&#xff09;AI绘画广场自定…

行业动态 - Zhaga 常见问题解答

本文采用chatGPT 3.5翻译润色&#xff0c;内容来自于Zhaga联盟官网Zhaga FAQ [1]&#xff0c;原文网页提供了更多的延伸阅读资料&#xff0c;可点击文末链接访问。另外不得不说&#xff0c;chatGPT对文字的优化调整功能太好用了。 ​ 1. "Zhaga"这个名字的由来和含义…

Nuxt 菜鸟入门学习笔记二:配置

文章目录 Nuxt 配置环境覆盖环境变量和私有令牌 应用配置runtimeConfig 与 app.config外部配置文件Vue 配置支持配置 Vite配置 webpack启用试验性 Vue 功能 Nuxt 官网地址&#xff1a; https://nuxt.com/ 默认情况下&#xff0c;Nuxt 的配置涵盖了大多数用例。nuxt.config.ts …

【雕爷学编程】Arduino动手做(172)---WeMos D1开发板模块4

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

为什么 Raft 原生系统是流数据的未来

虽然Apache Kafka正在逐步引入KRaft以简化其一致性方法&#xff0c;但基于Raft构建的系统对于未来的超大规模工作负载显示出更多的潜力。 ​共识是一致性分布式系统的基础。为了在不可避免的崩溃事件中保证系统的可用性&#xff0c;系统需要一种方式来确保集群中的每个节点保持…

快速跑 nerf instant-ngp 快速调试与配置,跑自己的数据

1.下载Anaconda3 2.打开Anaconda Prompt (Anaconda) 创建虚拟环境 conda create -n nerf-ngp python3.8切换到虚拟环境 conda activate nerf-ngp安装相关依赖包 pip install commentjson imageio numpy opencv-python-headless pybind11 pyquaternion scipy tqdm安装完毕后…

现在设计师都在用哪些工具做UI设计

随着国内企业在用户交互方面的竞争&#xff0c;UI设计的未来是无限的。 如果你仍然或只是在寻找一个合适的UI设计工具&#xff0c;那么这篇文章应该非常适合你。 1.即时设计 即时设计是一款免费的在线 UI 设计工具&#xff0c;无系统限制&#xff0c;浏览器打开即可使用&…

Java面试准备篇:全面了解面试流程与常见问题

文章目录 1.1 Java面试概述1.2 面试流程和注意事项1.3 自我介绍及项目介绍1.4 常见面试问题 在现代职场中&#xff0c;面试是求职过程中至关重要的一环&#xff0c;特别是对于Java开发者而言。为了帮助广大Java开发者更好地应对面试&#xff0c;本文将提供一份全面的Java面试准…

Python中安装pyinstaller并打包为exe可执行程序

环境&#xff1a;vs2022 win10 python3.7.8 工具&#xff1a;pyinstaller 1、安装pyinstaller&#xff0c;cmd --> pip install pyinstaller 2、安装完成后&#xff0c;打开cmd&#xff0c;输入命令&#xff1a;pyinstaller -F xxx.py &#xff0c;xxx为py文件的全路径&am…

超细整理,Python接口自动化测试-关联参数(购物接口实例)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 什么是参数关联&a…

Hadoop生态体系-2

目录标题 1、MapReduce介绍2、数据仓库3、HIVE4、HQL4.1 hive读写文件机制4.2 Hive数据存储路径 1、MapReduce介绍 思想&#xff1a;分而治之 map:“分”&#xff0c;即把复杂的任务分解为若干个“简单的任务”来处理。可以进行拆分的前提是这些小任务可以并行计算&#xff0c…