android 進度條_Android自定义控件:进度条的四种实现方式(Progress Wheel的解析)...

// 在这里我们不能使用getWidth()和getHeight()。

// 因为这两个方法只能在View的布局完成后才能使用,而一个View的绘制过程是先绘制元素,再绘制Layout

// 所以我们必须使用getMeasuredWidth()和getMeasuredHeight()

int size = 0;

int width = getMeasuredWidth();

int height = getMeasuredHeight();

int widthWithoutPadding = width - getPaddingLeft() - getPaddingRight();

int heigthWithoutPadding = height - getPaddingTop() - getPaddingBottom();

// 最后我们用一些简单的逻辑去计算View的大小并调用setMeasuredDimension()去设置View的大小

// 在比较View的长宽前我们不考虑间距,但当我们设置View所需要绘制的面积时,我们要考虑它

// 不考虑间距的View(View内的实际画面)此时就应该是方形的,但是由于间距的存在,最终View所占的面积可能不是方形的

if (widthWithoutPadding > heigthWithoutPadding) {

size = heigthWithoutPadding;

} else {

size = widthWithoutPadding;

}

// 如果你重写了onMeasure()方法,你必须调用setMeasuredDimension()方法

// 这是你设置View大小的唯一途径

// 如果你不调用setMeasuredDimension()方法,父控件会抛出异常,并且程序会崩溃

// 如果我们使用了超类的onMeasure()方法,我们就不是那么需要setMeasuredDimension()方法

// 然而,重写onMeasure()方法是为了改变既有的绘制流程,所以我们必须调用setMeasuredDimension()方法以达到我们的目的

setMeasuredDimension(size + getPaddingLeft() + getPaddingRight(), size + getPaddingTop() + getPaddingBottom());

}

/**

* 使用onSizeChanged方法代替onAttachedToWindow获得View的面积

* 因为这个方法会在测量了MATCH_PARENT和WRAP_CONTENT后马上被调用

* 使用获得的面积设置View

*/

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

// Share the dimensions

layout_width = w;

layout_height = h;

setupBounds();

setupPaints();

invalidate();

}

/**

* 设置我们想要绘制的progress wheel的颜色

*/

private void setupPaints() {

barPaint.setColor(barColor);

barPaint.setAntiAlias(true);

barPaint.setStyle(Style.STROKE);

barPaint.setStrokeWidth(barWidth);

rimPaint.setColor(rimColor);

rimPaint.setAntiAlias(true);

rimPaint.setStyle(Style.STROKE);

rimPaint.setStrokeWidth(rimWidth);

circlePaint.setColor(circleColor);

circlePaint.setAntiAlias(true);

circlePaint.setStyle(Style.FILL);

textPaint.setColor(textColor);

textPaint.setStyle(Style.FILL);

textPaint.setAntiAlias(true);

textPaint.setTextSize(textSize);

contourPaint.setColor(contourColor);

contourPaint.setAntiAlias(true);

contourPaint.setStyle(Style.STROKE);

contourPaint.setStrokeWidth(contourSize);

}

/**

* 设置元素的边界

*/

private void setupBounds() {

// 为了保持宽度和长度的一致,我们要获得layout_width和layout_height中较小的一个,从而绘制一个圆

int minValue = Math.min(layout_width, layout_height);

// 计算在绘制过程中在x,y方向的偏移量

int xOffset = layout_width - minValue;

int yOffset = layout_height - minValue;

// 间距加上偏移量

paddingTop = this.getPaddingTop() + (yOffset / 2);

paddingBottom = this.getPaddingBottom() + (yOffset / 2);

paddingLeft = this.getPaddingLeft() + (xOffset / 2);

paddingRight = this.getPaddingRight() + (xOffset / 2);

int width = getWidth(); //this.getLayoutParams().width;

int height = getHeight(); //this.getLayoutParams().height;

rectBounds = new RectF(paddingLeft,

paddingTop,

width - paddingRight,

height - paddingBottom);

circleBounds = new RectF(paddingLeft + barWidth,

paddingTop + barWidth,

width - paddingRight - barWidth,

height - paddingBottom - barWidth);

circleInnerContour = new RectF(circleBounds.left + (rimWidth / 2.0f) + (contourSize / 2.0f), circleBounds.top + (rimWidth / 2.0f) + (contourSize / 2.0f), circleBounds.right - (rimWidth / 2.0f) - (contourSize / 2.0f), circleBounds.bottom - (rimWidth / 2.0f) - (contourSize / 2.0f));

circleOuterContour = new RectF(circleBounds.left - (rimWidth / 2.0f) - (contourSize / 2.0f), circleBounds.top - (rimWidth / 2.0f) - (contourSize / 2.0f), circleBounds.right + (rimWidth / 2.0f) + (contourSize / 2.0f), circleBounds.bottom + (rimWidth / 2.0f) + (contourSize / 2.0f));

fullRadius = (width - paddingRight - barWidth) / 2;

circleRadius = (fullRadius - barWidth) + 1;

}

/**

* 从XML中解析控件的属性

*

* @param a the attributes to parse

*/

private void parseAttributes(TypedArray a) {

barWidth = (int) a.getDimension(R.styleable.ProgressWheel_barWidth,

barWidth);

rimWidth = (int) a.getDimension(R.styleable.ProgressWheel_rimWidth,

rimWidth);

spinSpeed = (int) a.getDimension(R.styleable.ProgressWheel_spinSpeed,

spinSpeed);

delayMillis = a.getInteger(R.styleable.ProgressWheel_delayMillis,

delayMillis);

if (delayMillis < 0) {

delayMillis = 0;

}

barColor = a.getColor(R.styleable.ProgressWheel_barColor, barColor);

barLength = (int) a.getDimension(R.styleable.ProgressWheel_barLength,

barLength);

textSize = (int) a.getDimension(R.styleable.ProgressWheel_textSize,

textSize);

textColor = (int) a.getColor(R.styleable.ProgressWheel_textColor,

textColor);

//如果text是空的,就无视它

if (a.hasValue(R.styleable.ProgressWheel_text)) {

setText(a.getString(R.styleable.ProgressWheel_text));

}

rimColor = (int) a.getColor(R.styleable.ProgressWheel_rimColor,

rimColor);

circleColor = (int) a.getColor(R.styleable.ProgressWheel_circleColor,

circleColor);

contourColor = a.getColor(R.styleable.ProgressWheel_contourColor, contourColor);

contourSize = a.getDimension(R.styleable.ProgressWheel_contourSize, contourSize);

// 使用TypedArray获得控件属性时必须要注意:使用结束后必须回收TypedArray的对象

a.recycle();

}

//----------------------------------

//动画

//----------------------------------

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

//绘制内圆

canvas.drawArc(circleBounds, 360, 360, false, circlePaint);

//绘制边界

canvas.drawArc(circleBounds, 360, 360, false, rimPaint);

canvas.drawArc(circleOuterContour, 360, 360, false, contourPaint);

canvas.drawArc(circleInnerContour, 360, 360, false, contourPaint);

//绘制条纹

if (isSpinning) {

canvas.drawArc(circleBounds, progress - 90, barLength, false,

barPaint);

} else {

canvas.drawArc(circleBounds, -90, progress, false, barPaint);

}

//绘制我们想要设置的文字 (并让它显示在圆水平和垂直方向的中心处)

float textHeight = textPaint.descent() - textPaint.ascent();

float verticalTextOffset = (textHeight / 2) - textPaint.descent();

for (String s : splitText) {

float horizontalTextOffset = textPaint.measureText(s) / 2;

canvas.drawText(s, this.getWidth() / 2 - horizontalTextOffset,

this.getHeight() / 2 + verticalTextOffset, textPaint);

}

if (isSpinning) {

scheduleRedraw();

}

}

private void scheduleRedraw() {

progress += spinSpeed;

if (progress > 360) {

progress = 0;

}

postInvalidateDelayed(delayMillis);

}

/**

* 判断wheel是否在旋转

*/

public boolean isSpinning() {

if(isSpinning){

return true;

} else {

return false;

}

}

/**

* 重设进度条的值

*/

public void resetCount() {

progress = 0;

setText("0%");

invalidate();

}

/**

* 停止进度条的旋转

*/

public void stopSpinning() {

isSpinning = false;

progress = 0;

postInvalidate();

}

/**

* 让进度条开启旋转模式

*/

public void spin() {

isSpinning = true;

postInvalidate();

}

/**

* 让进度条每次增加1(最大值为360)

*/

public void incrementProgress() {

isSpinning = false;

progress++;

if (progress > 360)

progress = 0;

setText(Math.round(((float) progress / 360) * 100) + "%");

postInvalidate();

}

/**

* 设置进度条为一个确切的数值

*/

public void setProgress(int i) {

isSpinning = false;

progress = i;

postInvalidate();

}

//----------------------------------

//get和set方法

//----------------------------------

/**

* 设置progress bar的文字并不需要刷新View

*

* @param text the text to show ('\n' constitutes a new line)

*/

public void setText(String text) {

this.text = text;

splitText = this.text.split("\n");

}

public int getCircleRadius() {

return circleRadius;

}

public void setCircleRadius(int circleRadius) {

this.circleRadius = circleRadius;

}

public int getBarLength() {

return barLength;

}

public void setBarLength(int barLength) {

this.barLength = barLength;

}

public int getBarWidth() {

return barWidth;

}

public void setBarWidth(int barWidth) {

this.barWidth = barWidth;

if ( this.barPaint != null ) {

this.barPaint.setStrokeWidth( this.barWidth );

}

}

public int getTextSize() {

return textSize;

}

public void setTextSize(int textSize) {

this.textSize = textSize;

if ( this.textPaint != null ) {

this.textPaint.setTextSize( this.textSize );

}

}

public int getPaddingTop() {

return paddingTop;

}

public void setPaddingTop(int paddingTop) {

this.paddingTop = paddingTop;

}

public int getPaddingBottom() {

return paddingBottom;

}

public void setPaddingBottom(int paddingBottom) {

this.paddingBottom = paddingBottom;

}

public int getPaddingLeft() {

return paddingLeft;

}

public void setPaddingLeft(int paddingLeft) {

this.paddingLeft = paddingLeft;

}

public int getPaddingRight() {

return paddingRight;

}

public void setPaddingRight(int paddingRight) {

this.paddingRight = paddingRight;

}

public int getBarColor() {

return barColor;

}

public void setBarColor(int barColor) {

this.barColor = barColor;

if ( this.barPaint != null ) {

this.barPaint.setColor( this.barColor );

}

}

public int getCircleColor() {

return circleColor;

}

public void setCircleColor(int circleColor) {

this.circleColor = circleColor;

if ( this.circlePaint != null ) {

this.circlePaint.setColor( this.circleColor);

}

}

public int getRimColor() {

return rimColor;

}

public void setRimColor(int rimColor) {

this.rimColor = rimColor;

if ( this.rimPaint != null ) {

this.rimPaint.setColor( this.rimColor );

}

}

public Shader getRimShader() {

return rimPaint.getShader();

}

public void setRimShader(Shader shader) {

this.rimPaint.setShader(shader);

}

public int getTextColor() {

return textColor;

}

public void setTextColor(int textColor) {

this.textColor = textColor;

if ( this.textPaint != null ) {

this.textPaint.setColor( this.textColor );

}

}

public int getSpinSpeed() {

return spinSpeed;

}

public void setSpinSpeed(int spinSpeed) {

this.spinSpeed = spinSpeed;

}

public int getRimWidth() {

return rimWidth;

}

public void setRimWidth(int rimWidth) {

this.rimWidth = rimWidth;

if ( this.rimPaint != null ) {

this.rimPaint.setStrokeWidth( this.rimWidth );

}

}

public int getDelayMillis() {

return delayMillis;

}

public void setDelayMillis(int delayMillis) {

this.delayMillis = delayMillis;

}

public int getContourColor() {

return contourColor;

}

public void setContourColor(int contourColor) {

this.contourColor = contourColor;

if ( contourPaint != null ) {

this.contourPaint.setColor( this.contourColor );

}

}

public float getContourSize() {

return this.contourSize;

}

public void setContourSize(float contourSize) {

this.contourSize = contourSize;

if ( contourPaint != null ) {

this.contourPaint.setStrokeWidth( this.contourSize );

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值