android 自定义progressbar demo,Android 自定义进度条ColorfulProgressbar,原理简单、效果还行...

效果图:

b3b56e48cae497f242bd348087108392.gif

demo效果演示

演示Demo

特性

与原生Progress相比,感觉更漂亮一点,可以显示进度值,背景凹凸感明显,进度条效果更加立体。

原理说明

额,挺简单的。不过感觉我的做法有点复杂了,我先自定义了一个View,专门作为进度条的显示图层,如下所示

5bbe2983f2fe

将其布局在高度不超过20dp的ColorfulProgressBar父布局中,设置Y方向的偏移量,然后动画循环改变Y坐标,实现斜条滚动的动画效果,当你调用setProgress方法时,则改变其在父布局的X坐标实现进度显示的功能,进度文字同样原理添加到了父布局中。

项目地址

相关代码

ColorfulProgressbar.java

package com.capton.colorfulprogressbar;

import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.util.AttributeSet;

import android.util.Log;

import android.view.Gravity;

import android.view.ViewGroup;

import android.view.animation.LinearInterpolator;

import android.view.animation.TranslateAnimation;

import android.widget.TextView;

/**

* Created by capton on 2017/8/10.

*/

public class ColorfulProgressbar extends ViewGroup {

public static final String STYLE_NORMAL="normal"; //正常单色样式

public static final String STYLE_COLORFUL="colorful"; //双色样式

public String style="colorful";

private ColorfulView colofulView; //双色View

private TextView progressView; // 第二进度条

private TextView maskView; // 季度条白色渐变图层

private TextView percentView; //文字显示进度层

private Paint progressPaint=new Paint(); //颜色一画笔

private Paint progressPaint2=new Paint(); //颜色二画笔

private Paint backgroundPaint=new Paint(); //背景画笔

private int maxHeight; //ColorfulProgressbar高度最大值

private int mHeight; //ColorfulProgressbar高度

private int mWidth; //ColorfulProgressbar宽度

private long progress; //进度值

private long secondProgress; //第二进度值

private long maxProgress=100; //默然最大进度100

private int backgroundColor=getResources().getColor(R.color.progressBg); //背景颜色

private int secondProgressColor=getResources().getColor(R.color.secondProgressColor); //第二进度条颜色

private int progressColor=getResources().getColor(R.color.colorAccent); //进度条颜色一

private int progressColor2=getResources().getColor(R.color.ltcolorAccent); //进度条颜色二

private int percentColor=Color.DKGRAY; //进度文字的颜色,默认暗灰色

private int percentShadeColor=Color.WHITE; //进度文字的阴影颜色,默认白色

private TranslateAnimation translateAnimation; //双色进度条的动画

private boolean animationOn=true; //动画开启的标志位

private boolean animationCancle; //动画取消的标志位

private boolean showPercent=true; // 是否显示进度文字的标志位

private boolean setBackgroudColor; // 是否改变背景颜色的标志位

public ColorfulProgressbar(Context context) {

this(context,null);

}

public ColorfulProgressbar(Context context, AttributeSet attrs) {

this(context, attrs,0);

}

public ColorfulProgressbar(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

setWillNotDraw(false); //自定义ViewGroup,默认不调用onDraw方法,而这里有很多步骤需要在ondraw中操作,所以调用setWillNotDraw(false)

mHeight=DisplayUtil.dip2px(context,4); //默认进度条高度为4dp

getParameter(context,attrs);

}

/**

* 从xml中获取各个属性

* @param context

* @param attrs

*/

private void getParameter(Context context, AttributeSet attrs){

if(attrs!=null) {

TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ColorfulProgressbar);

style = ta.getString(R.styleable.ColorfulProgressbar_style);

if (!STYLE_NORMAL.equals(style) && !STYLE_COLORFUL.equals(style)) {

style = STYLE_COLORFUL; //如果没有在xml中显示设置style,默认使用双色进度条

}

progress = ta.getInteger(R.styleable.ColorfulProgressbar_progress, (int)progress);

secondProgress = ta.getInteger(R.styleable.ColorfulProgressbar_secondProgress,(int)secondProgress);

maxProgress = ta.getInteger(R.styleable.ColorfulProgressbar_max, (int) maxProgress);

backgroundColor = ta.getColor(R.styleable.ColorfulProgressbar_backgroundColor, backgroundColor);

progressColor = ta.getColor(R.styleable.ColorfulProgressbar_progressColor1, progressColor);

progressColor2 = ta.getColor(R.styleable.ColorfulProgressbar_progressColor2, progressColor2);

ta.recycle();

partition2= (float)this.progress/maxProgress; //进度条百分比

partition= (float)this.secondProgress/maxProgress; //第二进度条百分比

}

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

int widthSize=MeasureSpec.getSize(widthMeasureSpec);

int widthMode=MeasureSpec.getMode(widthMeasureSpec);

int heightSize=MeasureSpec.getSize(heightMeasureSpec);

int heightMode=MeasureSpec.getMode(heightMeasureSpec);

widthSize=widthMode==MeasureSpec.EXACTLY?widthSize:DisplayUtil.dip2px(getContext(),200);

heightSize=heightMode==MeasureSpec.EXACTLY?heightSize:DisplayUtil.dip2px(getContext(),4);

/*

* 当你设置高度大于20dp时,强制高度变为20dp,太高了不美观。

* */

maxHeight=DisplayUtil.dip2px(getContext(),20);

if(mHeight>maxHeight) {

mHeight = maxHeight;

}

/*

* 设置高度

* */

if(mHeight>0){

heightSize=mHeight;

}

/*

* 在高度小于10dp时,强制不能使用文字显示进度,因为高度实在是太小了,在这个高度下字体看不清楚,放在进度条外又不美观,只好折中设计了。

* */

if(mHeight

showPercent=false;

}

/*

* 设置宽度

* */

if(mWidth>0){

widthSize=mWidth;

}

setMeasuredDimension(widthSize,heightSize); //确定主视图宽高

}

boolean once;

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

if(!once) {

progressPaint.setColor(progressColor);

progressPaint2.setColor(progressColor2);

progressPaint.setAntiAlias(true);

progressPaint2.setAntiAlias(true);

progressView = new TextView(getContext());

progressView.setWidth(getMeasuredWidth());

progressView.setHeight(getMeasuredHeight());

progressView.setBackgroundColor(secondProgressColor);

switch (style) {

case STYLE_COLORFUL:

colofulView = new ColorfulView(getContext(), getMeasuredWidth(), progressPaint, progressPaint2);

break;

case STYLE_NORMAL:

colofulView = new ColorfulView(getContext(), getMeasuredWidth(), progressPaint, progressPaint);

break;

}

percentView = new TextView(getContext());

percentView.setText((int)((float)partition2*100)+"%");

percentView.setTextSize(DisplayUtil.px2sp(getContext(), (float) (getMeasuredHeight()*0.8)));

percentView.setGravity(Gravity.CENTER);

percentView.setShadowLayer(2,1,2,percentShadeColor);

percentView.setTextColor(percentColor);

percentView.measure(0,0);

int textWidth = percentView.getMeasuredHeight()*2;

int textHeight = percentView.getMeasuredHeight();

maskView = new TextView(getContext());

maskView.setWidth(getMeasuredWidth());

maskView.setHeight(getMeasuredHeight() * 2 / 3);

maskView.setBackgroundResource(R.drawable.progress_mask);

/*

* 依次添加第二进度条,双色进度条(第一进度条),白色渐变层,百分比文字显示层等四个子View

* */

addView(progressView);

addView(colofulView);

addView(maskView);

addView(percentView);

getChildAt(0).layout(0, 0, getMeasuredWidth(), getMeasuredHeight()); //布局第二进度条位置

int ChildHeight = getMeasuredWidth();

getChildAt(1).layout(0, -ChildHeight + getMeasuredHeight(), getMeasuredWidth(), getMeasuredWidth()); //布局双色进度条

/*

* 根据标识位,为双色进度条设置位移动画(无限向上移动,视觉上达到斜条向右移动的效果)

* */

if (animationOn) {

translateAnimation = new TranslateAnimation(0, 0, 0, ChildHeight - getMeasuredHeight());

translateAnimation.setDuration((long) (8000 * (float) getMeasuredWidth() / DisplayUtil.getScreenWidthPx(getContext())));

translateAnimation.setRepeatCount(-1);

translateAnimation.setInterpolator(new LinearInterpolator());

getChildAt(1).setAnimation(translateAnimation);

translateAnimation.start();

}

getChildAt(2).layout(0, 0, getMeasuredWidth(), getMeasuredHeight() * 2 / 3); //布局白色渐变层

getChildAt(3).layout(0, 0, textWidth,textHeight); //布局百分比文字显示层

/*

* 根据标志位,确定是否显示百分比文字显示层。

* */

if(showPercent){

getChildAt(3).setVisibility(VISIBLE);

}else {

getChildAt(3).setVisibility(GONE);

}

/*

* 设置默认背景图,你当然也可以使用纯色的资源。这里我用了一个黑色透明渐变的背景,呈现一个由阴影效果的凹槽

* */

setBackgroundResource(R.drawable.background);

once=true;

}

}

public void showPercentText(boolean showPercent){

this.showPercent=showPercent;

}

public int getSecondProgressColor() {

return secondProgressColor;

}

public void setSecondProgressColor(int secondProgressColor) {

this.secondProgressColor = secondProgressColor;

}

public void setSecondProgressColorRes(int secondProgressColorRes) {

this.secondProgressColor = getResources().getColor(secondProgressColorRes);

}

public int getPercentColor() {

return percentColor;

}

public void setPercentColorRes(int percentColorRes) {

this.percentColor = getResources().getColor(percentColorRes);

}

public int getPercentShadeColor() {

return percentShadeColor;

}

public void setPercentShadeColor(int percentShadeColor) {

this.percentShadeColor = percentShadeColor;

}

public void setPercentShadeColorRes(int percentShadeColorRes) {

this.percentShadeColor = getResources().getColor(percentShadeColorRes);

}

public String getStyle() {

return style;

}

public void setStyle(String style) {

this.style = style;

}

public int getProgressColor() {

return progressColor;

}

public void setProgressColor(int progressColor) {

this.progressColor = progressColor;

}

public void setProgressColorRes(int progressColorRes) {

this.progressColor = getResources().getColor(progressColorRes);

}

public int getProgressColor2() {

return progressColor2;

}

public void setProgressColor2(int progressColor2) {

this.progressColor2 = progressColor2;

}

public void setProgressColor2Res(int progressColor2Res) {

this.progressColor2 = getResources().getColor(progressColor2Res);

}

public void setAnimation(boolean animationOn){

this.animationOn=animationOn;

}

public long getSecondProgress() {

return secondProgress;

}

private float partition;

public void setSecondProgress(long secondProgress) {

this.secondProgress = secondProgress;

partition= (float)this.secondProgress/maxProgress;

}

public int getBackgroundColor() {

return backgroundColor;

}

public void setBackgroundColor(int backgroundColor) {

this.backgroundColor = backgroundColor;

setBackgroudColor=true;

}

public void setBackgroundColorRes(int backgroundColorRes) {

this.backgroundColor = getResources().getColor(backgroundColorRes);

setBackgroudColor=true;

}

public void setHeight(int height){

mHeight=height;

}

public void setWidth(int width){

mWidth=width;

}

public void setMaxProgress(long progress){

maxProgress=progress;

}

public long getMaxProgress(){

return maxProgress;

}

private float partition2;

public void setProgress(long progress){

this.progress=progress;

partition2= (float)this.progress/maxProgress;

}

public long getProgress(){

return this.progress;

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

if (getChildAt(0) != null) {

int moveX = getMeasuredWidth() - (int) (partition * getMeasuredWidth());

getChildAt(0).setX(-moveX);

}

if (getChildAt(1) != null) {

int moveX = getMeasuredWidth() - (int) (partition2 * getMeasuredWidth());

getChildAt(1).setX(-moveX);

}

if (getChildAt(2) != null) {

int moveX = getMeasuredWidth() - (int) (partition2 * getMeasuredWidth());

getChildAt(2).setX(-moveX);

}

if (getChildAt(3) != null) {

if(getChildAt(1).getX()+getMeasuredWidth()>getChildAt(3).getMeasuredHeight()*2) {

getChildAt(3).setX(getChildAt(1).getX()+getMeasuredWidth()-getChildAt(3).getMeasuredHeight()*2);

}

percentView.setText((int) ((float) partition2 * 100) + "%");

/*

* 根据标志位,确定是否显示百分比文字显示层。

* */

if(showPercent){

getChildAt(3).setVisibility(VISIBLE);

}else {

getChildAt(3).setVisibility(GONE);

}

}

if (!animationOn) {

if (translateAnimation != null) {

translateAnimation.cancel();

animationCancle = true;

}

} else {

if (animationCancle) {

Log.w("onDraw", "translateAnimation animationCancle");

translateAnimation.reset();

getChildAt(1).setAnimation(translateAnimation);

translateAnimation.startNow();

animationCancle = false;

}

}

if(setBackgroudColor) {

backgroundPaint.setAntiAlias(true);

backgroundPaint.setColor(backgroundColor);

canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), backgroundPaint);

}

}

}

也是挺简单的,欢迎大家来踩呀!

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

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

相关文章

android os自动安裝软件,[图]Bliss OS 12进入开发阶段:可在桌面设备上安装Android 10系统...

此外还对电池进行了优化,添加了额外的安全性选项和相关功能,支持大部分主流游戏手柄,兼容ARM / ARM64应用程序。目前Bliss OS 12已经进入早期开发阶段,有望让您在PC上运行最新的Android 10移动操作系统。Bliss OS开发人员说&#…

android+版本升级的时候会清楚数据马,android主进程销毁了,线程会不会也销毁?...

Android Activity 销毁后子线程会不会被GC回收曾想当然地认为页面被finish之后线程会被android 虚拟机的垃圾回收机制回收掉。于是用页面跳转做测试测试代码结果有点意外,页面被销毁后定时器依然在执行。退出应用定时器还在执行。UI线程被结束掉,UI线程里…

mate7安装android o,华为Mate7升级安卓6.0详细教程

来讲一下华为Mate7升级安卓6.0(EMUI4.0)M版本详细图文教程吧,新的一年了,大家都迫不及待的想升级一下EMUI4.0,但是很多朋友都不知道怎样来升级,下面刷机网小编就来给大家仔细说一说吧,教程都在下面己经整理好了&#x…

html自动图片尺寸,关于html:CSS背景图像适合宽度,高度应按比例自动缩放

我有body {background: url(images/background.svg);}期望的效果是该背景图像的宽度等于页面的宽度,高度变化以保持比例。 例如 如果原始图像恰好是100 * 200(任何单位)且正文宽度为600px,则背景图像最终应为1200px高。 如果调整窗口大小,高度…

html定位的所有属性,HTML CSS定位属性详解 嘿嘿嘿

定位属性:Position作用:检索或者设置元素的定位方式“(改变元素位置)定位的步骤:1.给元素添加position属性 证明该元素要做位置变2.确定参照物!(通过position的属性值来确定 )3.确定坐标 left right top bottomPosition的属性值&a…

postman响应html,Postman工具——请求与响应(示例代码)

两个内容: Request 请求和 Response 响应,下面就开始了。一、Request 请求Request 请求,我们只介绍常用的四种:GET、POST、PUT、DELETE,其他类型的就不展开介绍了。另外,我们今天测试的项目是基于 RESTful …

2021高考无准考证成绩查询,2021考研没有准考证号怎么查成绩

2021考研没有准考证号怎么查成绩2020-12-10 11:02:14文/徐克达考研初试结束后,大家最关心的就是成绩的事情了,那么考研没有准考证号怎么查成绩呢?下面是小编整理的详细内容,一起来看看吧!考研没有准考证号查成绩的方法…

c++ 如何确认网卡为无线网卡_笔记本无线网卡有哪几种 有必要升级吗

无线网卡是很多朋友购买笔记本时容易忽视的部分,相比较处理器、内存、显卡和硬盘,无线网卡几乎不可选,而且很少有厂商提到自家产品采用的无线网卡型号。大家可能遇到过这种情况:为什么手机可以连接到5Ghz,而自己的笔记…

计算机网络专业运动会入场式,运动会入场式解说词(精选10篇)

运动会入场式解说词(精选10篇)在学习、工作生活中,接触并使用解说词的人越来越多,解说词是依靠文字来对事物、事件或人物进行描述的口头说明解说的词。大家知道解说词的格式吗?以下是小编精心整理的运动会入场式解说词(精选10篇),…

gifcam使用缩小内存_Fedora 上的桌面环境内存占用测试 | Linux 中国

通常,根据功能、外观和其它品质,选择桌面是一件非常个人的偏好。但有时,你选择的桌面环境还会受到硬件限制。-- Troy DawsonFedora 中有 40 多种桌面环境(DE)。每种桌面环境都有自己的优点和缺点。通常,根据功能、外观和其它品质&…

优秀自我简介200字_全球战疫 翰墨传情——东方盛世杯网络公益书画展优秀作品【二】...

​本文纯手打原创,转发请标注出处!中国书画爱好者,是中华优秀传统文化的薪火传承者。他们用生命中最美好的时光与最深沉的情感,实践着伟大文化复兴而不自知。——书画家网经过评委的精心评选,“东方盛世杯”2020网络公…

fi sap 凭证冲销 稅_SAP 成本收集器与重复制造配置手册

1.检查产品成本收集器的评估变式OPN22.检查产品成本收集器的成本核算变式OKKN3.确定作业数量的成本核算变式4.内部作业估价的成本核算变式5.定义订单交货的货物接收评估6.定义利润分析码OKG17.定…

要怎么在计算机里清除桌面内存,电脑内存不足怎么办?怎么清理电脑内存?

当电脑内存不足,内存占用高,磁盘空间不够时,我们该如何对电脑进行清理呢?今天我们就一起来看看清理电脑内存的方法!一、结束进程中占用内存高的软件1.使用电脑组合键【CtrlShiftEsc】调出任务管理器,在【进…

axios传数组到后台_我是如何让公司后台管理系统焕然一新的

作者:yeyan1996https://juejin.im/post/5c76843af265da2ddd4a6dd0写在前面马上到了金三银四的时间,很多公司开启了今年第一轮招聘的热潮,虽说今年是互联网的寒冬,但是只要对技术始终抱有热情以及有过硬的实力,即使是寒…

学计算机买电脑显卡1605ti够吗,铭瑄GTX1660Ti显卡值得买吗 铭瑄GTX1660Ti终结者显卡评测...

铭瑄GTX1660Ti显卡怎么样?值得买吗?下面小编带来铭瑄GTX1660Ti终结者显卡评测,希望对大家有所帮助。铭瑄GTX1660Ti终结者显卡评测:2019年1月7日,英伟达发布了价格更加实惠的甜品级RTX显卡RTX2060,玩家们对于…

windows无法新建计算机对象,教您activex部件不能创建对象怎么解决

我们有时候在运行ASP程序的时候,会出现提示ActiveX部件不能创建对象,出现这个问题的原因,有可能是服务器系统重装了。那么当我们遇到电脑出现ActiveX部件不能创建对象怎么办?下面,小编给大家准备了activex部件不能创建…

全国计算机三级数据库考试题型,2015年全国计算机三级考试《数据库》测试题及答案...

2015年全国计算机三级考试《数据库》测试题及答案1.假定学生关系是S(S#,SNAME,SEX,AGE),课程关系是C(C#,CNAME,TEACHER),学生选课关系是SC(S#,C#,GRADE)。要查找选修 &qu…

七七计算机论文网,qepipnu

标签:长句英语基本单位毕业设计毕业论文杂谈英语毕业论文On the Techniques of Translating English LongSentences如有需要请联系 bstractTranslation is the most important means of communication betweendifferent countries and cultures,in which…

新系统如何测试软件,怎样检测电脑能否升级到最新的Windows11系统?官方检测工具帮你一招搞定!...

日前,微软正式发布了Windows11系统,新的Windows11操作系统不仅采用了全新的居中设计的开始键以及任务栏,同时还取消了Windows8引入的实时磁贴设计,取而代之的是最近文档、应用程序以及单独的搜索界面。再加上Windows11带来的全新的…

服务器个别目录下不能新建文件夹,域服务器不能创建sysvol和netlogon共享文件夹...

请教个问题。我这里有两台win2003sp2的DC,ip:172.16.1.2(PDC)和172.16.1.3(BDCexchange2003sp2);我发现我们的域服务器有问题,之前目录复制一直不成功,172.16.1.2(主域)的目录数据不能复制到172.16.1.3(bdc)&#xff0…