1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 自定义ProgressBar(包括自定义图片 带进度的圆形进度条 长方形进度条)

自定义ProgressBar(包括自定义图片 带进度的圆形进度条 长方形进度条)

时间:2019-04-14 16:28:38

相关推荐

自定义ProgressBar(包括自定义图片 带进度的圆形进度条 长方形进度条)

转载请注明原博客地址:/gdutxiaoxu/article/details/51545889

参考博客:/lmj623565791?viewmode=contents

ProgressBar简介

继承于View类,直接子类有AbsSeekBar和ContentLoadingProgressBar,其中AbsSeekBar的子类有SeekBar和RatingBar,可见这二者也是基于ProgressBar实现的。

1、ProgressBar有两个进度,一个是Android:progress,另一个是android:secondaryProgress。后者主要是为缓存需要所涉及的,比如在看网络视频时候都会有一个缓存的进度条以及还要一个播放的进度,在这里缓存的进度就可以是android:secondaryProgress,而播放进度就是android:progress,有了secondProgress,可以很方便定制ProgressBar。

2、ProgressBar分为确定的和不确定的,确定的是我们能明确看到进度,相反不确定的就是不清楚、不确定一个操作需要多长时间来完成,这个时候就需要用的不确定的ProgressBar了。属性android:indeterminate如果设置为true的话,那么ProgressBar就可能是圆形的滚动条或者水平的滚动条(由样式决定),但是我们一般时候,是直接使用Style类型来区分圆形还是水平ProgressBar的。

3、ProgressBar的样式设定其实有两种方式,在API文档中说明的方式如下:

Widget.ProgressBar.HorizontalWidget.ProgressBar.SmallWidget.ProgressBar.LargeWidget.ProgressBar.InverseWidget.ProgressBar.Small.InverseWidget.ProgressBar.Large.Inverse 使用的时候可以这样:style="@android:style/Widget.ProgressBar.Small",另外还有一种方式就是使用系统的attr,下面的方式是系统的style:

style="?android:attr/progressBarStyle"style="?android:attr/progressBarStyleHorizontal"style="?android:attr/progressBarStyleInverse"style="?android:attr/progressBarStyleLarge"style="?android:attr/progressBarStyleLargeInverse"style="?android:attr/progressBarStyleSmall"style="?android:attr/progressBarStyleSmallInverse"style="?android:attr/progressBarStyleSmallTitle"先看一下效果图

源代码下载地址:/gdutxiaoxu/CustomProgressBar.git

1 修改ProgressBar的图片

1)第一个效果的实现非常简单

只需要修改ProgressBar的style即可

<style name="progressBar_custom_drawable" parent="@android:style/Widget.ProgressBar.Small"><item name="android:indeterminateDrawable">@drawable/progressbar_circle_1</item><item name="android:minWidth">25dp</item><item name="android:minHeight">25dp</item><item name="android:maxWidth">60dp</item><item name="android:maxHeight">60dp</item></style>

其中修改属性即可更改为我们想要的效果

<item name="android:indeterminateDrawable">@drawable/progressbar_circle_1</item>

2)这个形状我们可以借助代码实现

在Drawable目录下新建一个XML文件

<?xml version="1.0" encoding="utf-8"?><rotate xmlns:android="/apk/res/android" android:fromDegrees="0"android:pivotX="50%" android:pivotY="50%" android:toDegrees="360"><shape android:innerRadiusRatio="3" android:shape="ring" android:thicknessRatio="8"android:useLevel="false"><gradient android:centerColor="#FFFFFF" android:centerY="0.50"android:endColor="#1E90FF"android:startColor="#000000" android:type="sweep"android:useLevel="false" /></shape></rotate>

2 自定义长方形进度条

这种效果我们是通过继承ProgressBar实现的a 先讲一下实现思路 横向那个进度条,主要是通过是通过Canvas类的drawLine()和drawText()方法实现的, 1)要解决的问题,怎样拿到拿到控件的宽度,(不了解的请先自行了解View的绘制原理,本篇博客的重点不在这里,就不详细说了,下面会给出测量的代码 2)拿到宽度以后,我们再通过getProgress()拿到进度,按比例控制绘制线的长短,这样就实现了。 为了控件使用起来方便,我们使用到了自定义属性,如果多自定义属性不熟悉的,建议参考鸿洋的这篇博客:/lmj623565791/article/details/45022631 下面给出源代码

1)在value目录下新建attr_progress_bar xml文件

<?xml version="1.0" encoding="utf-8"?><resources><declare-styleable name="BaseProgressBar"><attr name="progress_unreached_color" format="color" /><attr name="progress_reached_color" format="color" /><attr name="progress_reached_bar_height" format="dimension" /><attr name="progress_unreached_bar_height" format="dimension" /><attr name="progress_text_size" format="dimension" /><attr name="progress_text_color" format="color" /><attr name="progress_text_offset" format="dimension" /><attr name="progress_text_visibility" format="enum"><enum name="visible" value="0" /><enum name="invisible" value="1" /></attr></declare-styleable><declare-styleable name="RoundProgressBarWidthNumber"><attr name="radius" format="dimension" /></declare-styleable></resources>

2)在构造器里面获取我们的自定义属性,为了代码的复用,我们把它放到基类BaseProgressBar

/*** get the styled attributes** @param attrs*/private void obtainStyledAttributes(AttributeSet attrs) {// init values from custom attributesfinal TypedArray attributes = getContext().obtainStyledAttributes(attrs, R.styleable.BaseProgressBar);mTextColor = attributes.getColor(R.styleable.BaseProgressBar_progress_text_color,DEFAULT_TEXT_COLOR);mTextSize = (int) attributes.getDimension(R.styleable.BaseProgressBar_progress_text_size,mTextSize);mReachedBarColor = attributes.getColor(R.styleable.BaseProgressBar_progress_reached_color,mTextColor);mUnReachedBarColor = attributes.getColor(R.styleable.BaseProgressBar_progress_unreached_color,DEFAULT_COLOR_UNREACHED_COLOR);mReachedProgressBarHeight = (int) attributes.getDimension(R.styleable.BaseProgressBar_progress_reached_bar_height,mReachedProgressBarHeight);mUnReachedProgressBarHeight = (int) attributes.getDimension(R.styleable.BaseProgressBar_progress_unreached_bar_height,mUnReachedProgressBarHeight);mTextOffset = (int) attributes.getDimension(R.styleable.BaseProgressBar_progress_text_offset,mTextOffset);int textVisible = attributes.getInt(R.styleable.BaseProgressBar_progress_text_visibility,VISIBLE);if (textVisible != VISIBLE) {mIfDrawText = false;}attributes.recycle();}public BaseProgressBar(Context context, AttributeSet attrs,int defStyle) {super(context, attrs, defStyle);obtainStyledAttributes(attrs);mPaint.setTextSize(mTextSize);mPaint.setColor(mTextColor);}

3)在onMeasure里面拿到我们空间的高度

<pre name="code" class="java">@Overrideprotected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int width = MeasureSpec.getSize(widthMeasureSpec);int height = measureHeight(heightMeasureSpec);setMeasuredDimension(width, height);mRealWidth = getMeasuredWidth() - getPaddingRight() - getPaddingLeft();}private int measureHeight(int measureSpec) {int result = 0;int specMode = MeasureSpec.getMode(measureSpec);int specSize = MeasureSpec.getSize(measureSpec);// 测量模式等于 MeasureSpec.EXACTLY,交给系统自己处理if (specMode == MeasureSpec.EXACTLY) {result = specSize;// 测量模式不等于 MeasureSpec.EXACTLY} else {// 测量模式等于MeasureSpec.UNSPECIFIE的时候自己处理float textHeight = (mPaint.descent() - mPaint.ascent());result = (int) (getPaddingTop() + getPaddingBottom() + Math.max(Math.max(mReachedProgressBarHeight,mUnReachedProgressBarHeight), Math.abs(textHeight)));// 测量模式等于MeasureSpec.AT_MOST的时候,取较小的一个if (specMode == MeasureSpec.AT_MOST) {result = Math.min(result, specSize);}}return result;}

4)在onDraw里面绘制

@Overrideprotected synchronized void onDraw(Canvas canvas) {canvas.save();canvas.translate(getPaddingLeft(), getHeight() / 2);boolean noNeedBg = false;float radio = getProgress() * 1.0f / getMax();float progressPosX = (int) (mRealWidth * radio);String text = getProgress() + "%";// mPaint.getTextBounds(text, 0, text.length(), mTextBound);float textWidth = mPaint.measureText(text);float textHeight = (mPaint.descent() + mPaint.ascent()) / 2;if (progressPosX + textWidth > mRealWidth) {progressPosX = mRealWidth - textWidth;noNeedBg = true;}// draw reached barfloat endX = progressPosX - mTextOffset / 2;if (endX > 0) {mPaint.setColor(mReachedBarColor);mPaint.setStrokeWidth(mReachedProgressBarHeight);canvas.drawLine(0, 0, endX, 0, mPaint);}// draw progress bar// measure text boundif (mIfDrawText) {mPaint.setColor(mTextColor);canvas.drawText(text, progressPosX, -textHeight, mPaint);}// draw unreached barif (!noNeedBg) {float start = progressPosX + mTextOffset / 2 + textWidth;mPaint.setColor(mUnReachedBarColor);mPaint.setStrokeWidth(mUnReachedProgressBarHeight);canvas.drawLine(start, 0, mRealWidth, 0, mPaint);}canvas.restore();}

到这里,实现思已经完毕 源代码下载地址:/gdutxiaoxu/CustomProgressBar.git

3 自定义圆形进度条

实现思路 1)继承BaseProgressBar,在构造器里面获取我们需要的自定义属性 2)在onMeasure里面拿到我们空间的高度 3)在onDraw里面绘制圆和文本(先绘制一个细一点的圆,然后绘制一个粗一点的弧度,二者叠在一起就行。文本呢,绘制在中间) 代码如下

package com.xujun.administrator.customprogressbar;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Paint.Cap;import android.graphics.Paint.Style;import android.graphics.RectF;import android.util.AttributeSet;public class RoundProgressBarWidthNumber extendsBaseProgressBar {/*** mRadius of view*/private int mRadius = dp2px(30);private int mMaxPaintWidth;public RoundProgressBarWidthNumber(Context context) {this(context, null);}public RoundProgressBarWidthNumber(Context context, AttributeSet attrs) {super(context, attrs);mReachedProgressBarHeight = (int) (mUnReachedProgressBarHeight * 2.5f);TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.RoundProgressBarWidthNumber);mRadius = (int) ta.getDimension(R.styleable.RoundProgressBarWidthNumber_radius, mRadius);ta.recycle();mPaint.setStyle(Style.STROKE);mPaint.setAntiAlias(true);mPaint.setDither(true);mPaint.setStrokeCap(Cap.ROUND);}/*** 这里默认在布局中padding值要么不设置,要么全部设置*/@Overrideprotected synchronized void onMeasure(int widthMeasureSpec,int heightMeasureSpec) {mMaxPaintWidth = Math.max(mReachedProgressBarHeight,mUnReachedProgressBarHeight);int expect = mRadius * 2 + mMaxPaintWidth + getPaddingLeft()+ getPaddingRight();int width = resolveSize(expect, widthMeasureSpec);int height = resolveSize(expect, heightMeasureSpec);int realWidth = Math.min(width, height);mRadius = (realWidth - getPaddingLeft() - getPaddingRight() - mMaxPaintWidth) / 2;setMeasuredDimension(realWidth, realWidth);}@Overrideprotected synchronized void onDraw(Canvas canvas) {String text = getProgress() + "%";float textWidth = mPaint.measureText(text);float textHeight = (mPaint.descent() + mPaint.ascent()) / 2;canvas.save();canvas.translate(getPaddingLeft() + mMaxPaintWidth / 2, getPaddingTop()+ mMaxPaintWidth / 2);mPaint.setStyle(Style.STROKE);// draw unreaded barmPaint.setColor(mUnReachedBarColor);mPaint.setStrokeWidth(mUnReachedProgressBarHeight);canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);// draw reached barmPaint.setColor(mReachedBarColor);mPaint.setStrokeWidth(mReachedProgressBarHeight);float sweepAngle = getProgress() * 1.0f / getMax() * 360;canvas.drawArc(new RectF(0, 0, mRadius * 2, mRadius * 2), 0,sweepAngle, false, mPaint);// draw textmPaint.setStyle(Style.FILL);canvas.drawText(text, mRadius - textWidth / 2, mRadius - textHeight,mPaint);canvas.restore();}}

源代码下载地址:/gdutxiaoxu/CustomProgressBar.git

转载请注明原博客地址:/gdutxiaoxu/article/details/51545889

参考博客:/lmj623565791?viewmode=contents

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。