Android自定义水平渐变进度条
作者:hust_twj 发布时间:2022-06-02 14:22:42
标签:Android,进度条
先看进度条的效果:
具体实现:
新建类,继承自View,在onDraw中进行绘制:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
/**
*
* 自定义 进度条
* Created by wenjing.tang on 2017/8/7.
*/
public class CustomizedProgressBar extends View {
private float maxCount = 100; //进度条最大值
private float currentCount; //进度条当前值
// private Paint mPaint ;
private int mWidth,mHeight;
private Context mContext;
public CustomizedProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
public CustomizedProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public CustomizedProgressBar(Context context) {
super(context);
initView(context);
}
private void initView(Context context) {
mContext=context;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint mPaint = new Paint();
mPaint.setAntiAlias(true);
int round = mHeight/2; //半径
mPaint.setColor(getResources().getColor(R.color.white_alpha)); //设置边框背景颜色
RectF rectBg = new RectF(0, 0, mWidth, mHeight);
canvas.drawRoundRect(rectBg, round, round, mPaint);//绘制 最外面的大 圆角矩形,背景为白色
float section = currentCount/maxCount; //进度条的比例
RectF rectProgressBg = new RectF(0, 0, mWidth*section, mHeight);
Log.e("CustomizedProgressBar", currentCount+"");
Log.e("CustomizedProgressBar", section+"");
//Paint设置setColor(白色无透明)和setShader,只让setShader生效;不然前面setColor设置了透明度,透明度会生效,和setShader效果叠加
mPaint.setColor(getResources().getColor(R.color.white));
mPaint.setShader(getLinearGradient());
canvas.drawRoundRect(rectProgressBg, round, round, mPaint); //最左边的圆角矩形
if (maxCount != currentCount){ //如果不是100%,绘制第三段矩形
RectF rectProgressBg2 = new RectF(mWidth*section-round, 0, mWidth*section, mHeight);
mPaint.setShader(getLinearGradient());
canvas.drawRect(rectProgressBg2, mPaint);
}
}
private LinearGradient linearGradient;
private LinearGradient getLinearGradient(){
if(linearGradient==null){
linearGradient = new LinearGradient(0, 0, getWidth(), mHeight, new int[]{mContext.getResources().getColor(R.color.progress_color_1),
mContext.getResources().getColor(R.color.progress_color_2)}, null, Shader.TileMode.CLAMP); //根据R文件中的id获取到color
}
return linearGradient;
}
private int dipToPx(int dip) {
float scale = getContext().getResources().getDisplayMetrics().density;
return (int) (dip * scale + 0.5f * (dip >= 0 ? 1 : -1));
}
/***
* 设置最大的进度值
* @param maxCount 最大的进度值
*/
public void setMaxCount(float maxCount) {
this.maxCount = maxCount;
}
/***
* 设置当前的进度值
* @param currentCount 当前进度值
*/
public void setCurrentCount(float currentCount) {
this.currentCount = currentCount > maxCount ? maxCount : currentCount;
invalidate();
}
public float getMaxCount() {
return maxCount;
}
public float getCurrentCount() {
return currentCount;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthSpecMode == MeasureSpec.EXACTLY || widthSpecMode == MeasureSpec.AT_MOST) {
mWidth = widthSpecSize;
} else {
mWidth = 0;
}
if (heightSpecMode == MeasureSpec.AT_MOST || heightSpecMode == MeasureSpec.UNSPECIFIED) {
mHeight = dipToPx(18);
} else {
mHeight = heightSpecSize;
}
setMeasuredDimension(mWidth, mHeight);
}
}
其中用到的一些资源文件如下:
<!--自定义进度条背景颜色-->
<color name="white_alpha">#0c000000</color>
<!--自定义进度条渐变颜色-->
<color name="progress_color_1">#ff916b</color>
<color name="progress_color_2">#ffa94c</color>
要注意的是,在上面Java代码中,mPaint.setColor(getResources().getColor(R.color.white));这行很重要,因为进度条总共有三层,第一层是最外面的背景,第二层是进度,第三层如果不是100%才绘制,由于第一层背景有透明度,所以setColor设置了透明度,但虽然setShader,透明度还是会生效,两者效果叠加,效果是这样:
加上之后,Paint 第二次设置 setColor (白色无透明)和 setShader,只让 setShader 生效,进度条才会达到满意的效果;
用法:
Java代码中:
customizedProgressBar.setMaxCount(100);
integrity = dataCount/TOTAL_COUNT *100; //根据自己情况来初始化完整度
customizedProgressBar.setCurrentCount((int) integrity);
mTvtDataIntegrity.setText("完整度" + (int) integrity +"%");
xml文件中(不需要文字显示也可以):
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="18dp"
android:layout_marginStart="66dp"
android:layout_marginEnd="66dp"
android:layout_centerVertical="true">
<com.text.widget.CustomizedProgressBar
android:id="@+id/progress"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"/>
<TextView
android:id="@+id/tv_data_integrity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
tools:text="完整度35%"
android:textSize="10sp"
android:layout_centerInParent="true"/>
</RelativeLayout>
来源:http://blog.csdn.net/hust_twj/article/details/78063444


猜你喜欢
- 一、国际化准备资源文件,资源文件的命名格式如下:baseName_language_country.propertiesbaseName_l
- 引入:前段时间去银行办业务,排队的人那是真多,自己正式办理业务也就不到5分钟,但是却足足等了两个小时(相信很多人都遇到过这种情况),对这种服
- 常用的Dialog有确认对话框,单选按钮对话框,多选按钮对话框,复选按钮对话框另外还有自定义的对话框AlertDialog的常用方法setT
- 双保险线程,每次启动2个相同的线程,互相检测,避免线程死锁造成影响。两个线程都运行,但只有一个线程执行业务,但都会检测对方的时间戳 如果时间
- 本文实例为大家分享了C#实现飞行棋的具体代码,供大家参考,具体内容如下游戏规则如果玩家A踩到了玩家B,玩家B退6格踩到了1幸运轮盘,a交换位
- C#调用C++DLL传递结构体数组的终极解决方案在项目开发时,要调用C++封装的DLL,普通的类型C#上一般都对应,只要用DllImport
- 定义MD全称Message-Digest,即信息摘要,所以MD家族的算法也叫信息摘要算法MD家族有MD2、MD3、MD4、MD5,一代比一代
- 前言最近测试给我提了一个bug,说我之前提供的一个批量复制商品的接口,产生了重复的商品数据。追查原因之后发现,这个事情没想象中简单,可以说一
- 本文实例总结了C#实现启用与禁用本地网络的方式。分享给大家供大家参考,具体如下:1) 使用Hnetcfg.dll使用Add Referenc
- android通过google API获取天气信息public class WeatherActivity extends Activity
- 本文实例讲述了Android桌面插件App Widget用法。分享给大家供大家参考,具体如下:应用程序窗口小部件App Widgets应用程
- 先来看看要实现的效果图:对于安卓用户来说,手机应用市场说满天飞可是一点都不夸张,比如小米,魅族,百度,360,机锋,应用宝等等,当我们想上线
- 1、不知道为啥process.StartInfo.Arguments = "/c" + "start D:/T
- 过去的每一year,涌现出越来越多的Java框架。就像JavaScript,每个人都认为他们知道一个好的框架的功能应该是怎么样的。连我的老祖
- 如果问你在日常开发中用到的最多的一个 Java 类是什么,阿粉敢打赌绝对是 String.class。说到&n
- 下面还有投票,帮忙投个票👍前言最近在看某个开源项目代码并准备参与其中,代码过了一遍后发现多个自定义的配置文件用来装载业务配置代替数据库查询,
- 先看看效果图:1、XML布局引入<com.net168.lib.SortTabLayout android:id=&quo
- 一、概述在软件开发中,有些对象由于创建成本高、访问时需要与其它进程交互等原因,直接访问会造成系统速度慢、复杂度增大等问题。这时可以使用代理模
- 文章转自公众号:Coder梁(ID:Coder_LT) 1.类常量有的时候, 我们希望能给类当中定义一些常量,可以给所有类的对象使用。比如说
- 1 MyBatisPlusConfigMyBatisPlus配置类。package com.config;import