进度条(ProgressBar)也是UI界面中的一种很是使用的组件,一般用于向用户显示某个耗时完成的百分比。所以进度条能够动态的显示进度,所以避免长时间地执行某个耗时操做时,让用户感受程序失去了响应,从而更好的提升用户界面的有好性。android
Android支持几种风格的进度条,经过Style属性能够为进度条ProgressBar指定风格,该属性支持一下几个属性值。web
XML属性 | 说明 |
---|---|
android:max | 设置该进度条的最大值 |
android:progress | 设置该进度条的已完成进度值 |
android:progressDrawable | 设置该进度条的轨道的绘制形式 |
android:progressBarStyle | 默认进度条样式 |
android:progressBarStyleHorizontal | 水平进度条样式 |
android:progressBarStyleLarge | 大进度条样式 |
android:progressBarStyleSmall | 小进度条样式 |
上表中的android:progressDrawable用于指定进度条的轨道的绘制形式,该属性能够指定一个LayerDrawable对象(该对象能够经过在xml文件中用<layer-list>元素进行配置)的引用。canvas
ProgressBar提供了以下方法来操做完成百分比:ide
setProgress(int): 设置进度完成百分比。
incrementProgressBy(int): 设置进度条的进度增长或减小。当参数为正数时增长,反之则减小。svg
定义资源文件:gradient_progress_layer.xmlthis
<?xml version="1.0" encoding="UTF-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/background"> <shape> <corners android:radius="13dp" /> <solid android:color="#aaaaaa"/> </shape> </item> <item android:id="@android:id/secondaryProgress"> <clip> <shape> <corners android:radius="13dp" /> <gradient android:angle="270" android:centerColor="#000000" android:endColor="#000000" android:startColor="#000000" /> <padding android:bottom="2dp" android:left="2dp" android:right="2dp" android:top="2dp"/> </shape> </clip> </item> <item android:id="@android:id/progress"> <clip> <shape> <corners android:radius="13dp" /> <gradient android:angle="0" android:endColor="#1becbd" android:centerColor="#48c3dd" android:startColor="#739afe" /> <padding android:bottom="2dp" android:left="2dp" android:right="2dp" android:top="2dp"/> </shape> </clip> </item> </layer-list>
控件上引用:3d
<ProgressBar ... android:progressDrawable="@drawable/gradient_progress_layer" />
效果图:
code
public class ProgressView extends View { /** * 渐变颜色 */ private static final int[] SECTION_COLORS = {0xff123b9d, 0xff4e9bce, 0xff85f4fb}; /** * 进度条最大值 */ private float maxCount; /** * 进度条当前值 */ private float currentCount; /** * 画笔 */ private Paint mPaint; private int mWidth, mHeight;//设置宽度和高度 public ProgressView(Context context) { super(context); } public ProgressView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public ProgressView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint = new Paint(); mPaint.setAntiAlias(true); int round = mHeight / 2; //蓝色边框 //绘制阴影效果 int beginP = dipToPx(0); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(0xff00a3d5); mPaint.setStyle(Paint.Style.FILL); mPaint.setShadowLayer(100, 0, 0, Color.WHITE); RectF rectBg = new RectF(beginP, beginP, mWidth, mHeight); canvas.drawRoundRect(rectBg, round, round, mPaint); //深蓝色边框 mPaint.setColor(Color.rgb(7, 38, 85)); RectF rectBg1 = new RectF(beginP + 2, beginP + 2, mWidth - 2, mHeight - 2); canvas.drawRoundRect(rectBg1, round, round, mPaint); mPaint.setColor(0xff072655); RectF rectBlackBg = new RectF(beginP + 4, beginP + 4, mWidth - 4, mHeight - 4); canvas.drawRoundRect(rectBlackBg, round, round, mPaint); float section = currentCount / maxCount; RectF rectProgressBg = new RectF(beginP + 3, beginP + 3, (mWidth - 3) * section, mHeight - 3); if (section <= 1.0f / 3.0f) { if (section != 0.0f) { mPaint.setColor(SECTION_COLORS[0]); } else { mPaint.setColor(Color.TRANSPARENT); } } else { int count = (section <= 1.0f / 3.0f * 2) ? 2 : 3; int[] colors = new int[count]; System.arraycopy(SECTION_COLORS, 0, colors, 0, count); float[] positions = new float[count]; if (count == 2) { positions[0] = 0.0f; positions[1] = 1.0f - positions[0]; } else { positions[0] = 0.0f; positions[1] = (maxCount / 3) / currentCount; positions[2] = 1.0f - positions[0] * 2; } positions[positions.length - 1] = 1.0f; //线性渲染 LinearGradient shader = new LinearGradient(3, 3, (mWidth - 3) * section, mHeight - 3, colors, null, Shader.TileMode.MIRROR); mPaint.setShader(shader); } canvas.drawRoundRect(rectProgressBg, round, round, mPaint); } /** * dp转换成像素 * * @param dip * @return */ private int dipToPx(int dip) { float scale = getContext().getResources().getDisplayMetrics().density; return (int) (dip * scale + 0.5f * (dip >= 0 ? 1 : -1)); } /** * UNSPECIFIED 父容器没有对当前View有任何限制,当前View能够任意取尺寸 * EXACTLY 当前的尺寸就是当前View应该取的尺寸 * AT_MOST 当前尺寸是当前View能取的最大尺寸 * * @param widthMeasureSpec * @param heightMeasureSpec */ @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(25); } else { mHeight = heightSpecSize; } setMeasuredDimension(mWidth, mHeight); } /*** * 设置最大的进度值 * @param maxCount */ public void setMaxCount(float maxCount) { this.maxCount = maxCount; } /*** * 设置当前的进度值 * @param currentCount */ public void setCurrentCount(float currentCount) { this.currentCount = currentCount > maxCount ? maxCount : currentCount; invalidate(); } }