效果图:

方法讲解:

(1)invalidate()方法

invalidate()是用来刷新View的,必须是在UI线程中进行工作。比如在修改某个view的显示时, 调用invalidate()才能看到重新绘制的界面。invalidate()的调用是把之前的旧的view从主UI线程队列中pop掉。一般在自定义控件中会用到这个方法。

(2)RectF方法的应用

RectF是用来绘画矩形的方法。

RectF(left,top,right,bottom),四个参数的含义分别是父控件距离矩形左上右下边距的距离,以下用图来说明:

drawRoundRect方法是用来绘制圆角矩形的,它的参数如下: 
参数说明

rect:RectF对象。 
rx:x方向上的圆角半径。 
ry:y方向上的圆角半径。 
paint:绘制时所使用的画笔。

(3)onMeasure方法

指定自定义控件在屏幕上的大小,onMeasure方法的两个参数是由上一层控件 传入的大小,而且是模式和尺寸混合在一起的数值,需要MeasureSpec.getMode(widthMeasureSpec) 得到模式,MeasureSpec.getSize(widthMeasureSpec)得到尺寸。

onMeasure的几种模式分别为EXACTLY,AT_MOST,UNSPECIFIED。

[1]MeasureSpec.EXACTLY

MeasureSpec.EXACTLY是精确尺寸,当我们将控件的layout_width或layout_height指定为具体数值时如andorid:layout_width=”50dip”,或者为FILL_PARENT是,都是控件大小已经确定的情况,都是精确尺寸。

[2]MeasureSpec.AT_MOST

MeasureSpec.AT_MOST是最大尺寸,当控件的layout_width或layout_height指定为WRAP_CONTENT时,控件大小一般随着控件的子空间或内容进行变化,此时控件尺寸只要不超过父控件允许的最大尺寸即可。因此,此时的mode是AT_MOST,size给出了父控件允许的最大尺寸。

[3]MeasureSpec.UNSPECIFIED

MeasureSpec.UNSPECIFIED是未指定尺寸,这种情况不多,一般都是父控件是AdapterView,通过measure方法传入的模式。

实现步骤:

a、在values文件夹下新建attrs.xml,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<resources> <declare-styleable name="CircleProgressBar">
<attr name="croundColor" format="color"/>
<attr name="croundProgressColor" format="color"/>
<attr name="cfillColor" format="color"/>
<attr name="croundWidth" format="dimension"></attr>
<attr name="croundProgressWidth" format="dimension"></attr>
<attr name="ctextColor" format="color" />
<attr name="ctextSize" format="dimension" />
<attr name="cnumberSize" format="dimension" />
<attr name="cparaLable" format="string" />
<attr name="cunitLable" format="string" />
</declare-styleable> <declare-styleable name="RoundRectProgressBar">
<attr name="cbarRoundColor" format="color"/>
<attr name="cbarProgressColor" format="color"/>
<attr name="cbarFillColor" format="color"/>
<attr name="cbarOrientation">
  <enum name="HORIZONTAL" value="0"></enum>
  <enum name="VERTICAL" value="1"></enum>
</attr>
</declare-styleable> </resources>

  

b、新建RoundRectProgressBar类继承View

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.util.AttributeSet;
import android.view.View; /**
* 自定义圆角矩形进度条view
*
* @author xl
*/
public class RoundRectProgressBar extends View { private final static String TAG = RoundRectProgressBar.class.getSimpleName(); /**
* 画笔对象的引用
*/
private Paint paint; /**
* 圆角环的颜色
*/
private int roundColor; /**
* 进度的颜色
*/
private int fillProgressColor; /**
* 填充的颜色
*/
private int fillColor; /**
* 圆角矩形宽度
*/
private int roundWidth; /**
* 圆角矩形高度
*/
private int roundHeight; /**
* 进度条方向,0水平,1垂直
*/
private int barOrientation; /**
* 进度条最大值
*/
private float max = 100; /**
* 进度条当前值
*/
private float progress = 30; public RoundRectProgressBar(Context context) {
this(context, null);
} public RoundRectProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
} public RoundRectProgressBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
//获取画笔
paint = new Paint();
TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundRectProgressBar);
//获取自定义属性和默认值
roundColor = mTypedArray.getColor(R.styleable.RoundRectProgressBar_cbarRoundColor, Color.RED);
fillProgressColor = mTypedArray.getColor(R.styleable.RoundRectProgressBar_cbarProgressColor, Color.GREEN);
fillColor = mTypedArray.getColor(R.styleable.RoundRectProgressBar_cbarFillColor, Color.BLUE);
barOrientation = mTypedArray.getInt(R.styleable.RoundRectProgressBar_cbarOrientation, 0);
//回收TypedArray资源
mTypedArray.recycle();
} @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//设置抗锯齿效果
paint.setAntiAlias(true);
//设置画笔颜色
paint.setColor(roundColor);
//进度方向
if (barOrientation == 0) {
//水平,向右
try {
int round = roundHeight / 2;
//RectF:绘制矩形,四个参数分别是left,top,right,bottom,类型是单精度浮点数
RectF rf = new RectF(0, 0, roundWidth, roundHeight);
//绘制圆角矩形,背景色为画笔颜色
canvas.drawRoundRect(rf, round, round, paint);
//设置progress内部是灰色
paint.setColor(fillColor);
RectF rectBlackBg = new RectF(2, 2, roundWidth - 2, roundHeight - 2);
canvas.drawRoundRect(rectBlackBg, round, round, paint);
//设置进度条进度及颜色
float section = progress / max;
RectF rectProgressBg = new RectF(2, 2, (roundWidth - 2) * section, roundHeight - 2);
if (section != 0.0f) {
paint.setColor(fillProgressColor);
} else {
paint.setColor(Color.TRANSPARENT);
}
canvas.drawRoundRect(rectProgressBg, round, round, paint);
} catch (Exception e) {
e.printStackTrace();
}
} else {
//垂直,向上
try {
int round = roundWidth / 2;
//RectF:绘制矩形,四个参数分别是left,top,right,bottom,类型是单精度浮点数
RectF rf = new RectF(0, 0, roundWidth, roundHeight);
//绘制圆角矩形,背景色为画笔颜色
canvas.drawRoundRect(rf, round, round, paint);
//设置progress内部是灰色
paint.setColor(fillColor);
RectF rectBlackBg = new RectF(2, 2, roundWidth - 2, roundHeight - 2);
canvas.drawRoundRect(rectBlackBg, round, round, paint);
//设置进度条进度及颜色
float section = progress / max;
RectF rectProgressBg = new RectF(2, roundHeight - 2 - (roundHeight - 4) * section, roundWidth - 2, roundHeight - 2);
if (section != 0.0f) {
paint.setColor(fillProgressColor);
} else {
paint.setColor(Color.TRANSPARENT);
}
canvas.drawRoundRect(rectProgressBg, round, round, paint);
} catch (Exception e) {
e.printStackTrace();
}
}
} /**
* dip转px
*
* @param dip
* @return
*/
private int dipToPx(int dip) {
float scale = getContext().getResources().getDisplayMetrics().density;
//加0.5是为了四舍五入
return (int) (dip * scale + 0.5f * (dip >= 0 ? 1 : -1));
} /**
* 指定自定义控件在屏幕上的大小,onMeasure方法的两个参数是由上一层控件
* 传入的大小,而且是模式和尺寸混合在一起的数值,需要MeasureSpec.getMode(widthMeasureSpec)
* 得到模式,MeasureSpec.getSize(widthMeasureSpec)得到尺寸
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
//MeasureSpec.EXACTLY,精确尺寸
if (widthSpecMode == MeasureSpec.EXACTLY || widthSpecMode == MeasureSpec.AT_MOST) {
roundWidth = widthSpecSize;
} else {
roundWidth = 0;
}
if (heightSpecMode == MeasureSpec.EXACTLY || heightSpecMode == MeasureSpec.AT_MOST) {
roundHeight = heightSpecSize;
} else {
roundHeight = 0;
}
//MeasureSpec.AT_MOST,最大尺寸,只要不超过父控件允许的最大尺寸即可,MeasureSpec.UNSPECIFIED未指定尺寸
//if (heightSpecMode == MeasureSpec.AT_MOST || heightSpecMode == MeasureSpec.UNSPECIFIED) {
// roundHeight = dipToPx(20);
//} else {
// roundHeight = heightSpecSize;
//}
//设置控件实际大小
setMeasuredDimension(roundWidth, roundHeight);
} /**
* 设置进度
*
* @param progress
*/
public synchronized void setProgress(float progress) {
if (progress < 0) {
throw new IllegalArgumentException("value can not be negative");
}
if (progress > max) {
this.progress = max;
} else {
this.progress = progress;
}
postInvalidate();
} /**
* 设置最大值
*
* @param max
*/
public synchronized void setMax(float max) {
if (max < 0) {
throw new IllegalArgumentException("value can not be negative");
}
this.max = max;
} }

  

c、布局文件中引用activity_main.xml

<ups.invt.com.view.RoundRectProgressBar
android:id="@+id/bar"
android:layout_width="20dp"
android:layout_height="100dp"
android_custom:cbarRoundColor="@color/transparent"
android_custom:cbarFillColor="@color/white"
android_custom:cbarProgressColor="@color/bar_fill_color"
android_custom:cbarOrientation="VERTICAL"
android:layout_centerInParent="true"/>

  

d、MainActivity.java中设置进度

progress = (RoundRectProgressBar) findViewById(R.id.bar);
progress.setMax(100); progress.setProgress(80);

完!!!
————————————————

参考于:https://blog.csdn.net/xialong_927/article/details/86596932

Android自定义圆角矩形进度条2的更多相关文章

  1. Android 自定义 View 圆形进度条总结

    Android 自定义圆形进度条总结 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 微信公众号:牙锅子 源码:CircleProgress 文中如有纰漏,欢迎大家留言指出. 最近 ...

  2. Android 自定义圆形旋转进度条,仿微博头像加载效果

    微博 App 的用户头像有一个圆形旋转进度条的加载效果,看上去效果非常不错,如图所示: 据说 Instagram 也采用了这种效果.最近抽空研究了一下,最后实现的效果是这样: 基本上能模拟出个大概,代 ...

  3. android 自定义图片圆形进度条

    感觉话一个圆形进度条挺简单的 ,但是却偏偏给了几张图片让你话,说实话我没接触过,感觉好难,还好百度有大把的资源,一番努力下终于画出来了. 代码如下. package com.etong.cpms.wi ...

  4. Android简易实战教程--第十七话《自定义彩色环形进度条》

    转载请注明出处:http://blog.csdn.net/qq_32059827/article/details/52203533   点击打开链接 在Android初级教程里面,介绍了shape用法 ...

  5. Android零基础入门第52节:自定义酷炫进度条

    原文:Android零基础入门第52节:自定义酷炫进度条 Android系统默认的ProgressBar往往都不能满足实际开发需要,一般都会开发者自定义ProgressBar. 在Android开发中 ...

  6. Android 打造形形色色的进度条 实现可以如此简单

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/43371299 ,本文出自:[张鸿洋的博客] 1.概述 最近需要用进度条,秉着不重 ...

  7. Android 使用ProgressBar实现进度条

    ProgressBar简介ProgressBar是进度条组件,通常用于向用户展示某个耗时操作完成的进度,而不让用户感觉是程序失去了响应,从而更好地提升用户界面的友好型. 课程目标(1)制定Progre ...

  8. HTML5 Canvas自定义圆角矩形与虚线(Rounded Rectangle and Dash Line)

    HTML5 Canvas自定义圆角矩形与虚线(RoundedRectangle and Dash Line) 实现向HTML Canvas 2d context绘制对象中添加自定义的函数功能演示,如何 ...

  9. Android学习笔记- ProgressBar(进度条)

    本节引言: 本节给大家带来的是Android基本UI控件中的ProgressBar(进度条),ProgressBar的应用场景很多,比如 用户登录时,后台在发请求,以及等待服务器返回信息,这个时候会用 ...

随机推荐

  1. redis分享

    Redis介绍 ´Redis是一种基于键值对的NoSQL数据库. ´Redis基于内存来存放数据. ´速度快,官方给出读写性能可达到10万/秒(数据存内存,C语言实现,单线程架构). ´丰富的数据结构 ...

  2. Linxu:磁盘分区

    了解磁盘分区 磁盘的物理组成: 圆形的磁盘盘(主要记录数据的部分): 机械手臂,与在机械手臂上的磁盘读取头(可擦写磁盘盘上的数据): 主轴马达,可以转动磁盘盘,让机械手臂的读取头在磁盘盘上读写数据. ...

  3. 5. Vue - 小清单实例

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. ubuntu pdfium

    dept_tool export PATH=`pwd`/depot_tools:"$PATH" gn工具在内

  5. C++中的异常处理(中)

    为什么要在catch中重新抛出异常? #include <iostream> #include <string> using namespace std; void Demo( ...

  6. 小程序的flex布局

    小程序建议使用flex布局进行排版 flex就是一个盒装弹性布局 flex是一个容器,所有子元素都是他的成员 小程序的flex布局 定义布局 display:flex flex容器的属性: flex- ...

  7. 自己整理的模拟爬虫的user-agent

    自己经常用的一些爬虫用的user-agent头部 This XML file does not appear to have any style information associated with ...

  8. day80_10_29git冲突解决与短信服务redis

    一.开发中的操作. 在项目开发中,在工作区进行开发,开发结束后提交到本地版本库. 再拉取远程仓库,具体如下: """ 1.开发前,拉一次远程仓库 2.工作区进行开发 3. ...

  9. HTTP 与HTTPS 简单理解

      HTTP协议,即超文本传输协议(Hypertext transfer protocol).是一种详细规定了浏览器和万维网(WWW = World Wide Web)服务器之间互相通信的规则,通过因 ...

  10. idea多模块项目打开RunDashBoard(十)

    在使用spring cloud微服务时,多个服务可以以多个独立子模块(module)的形式放在一个project里面,当服务过多时,一个个启动往往不是很方便,idea有一个贴心的RunDashBoar ...