最近整理blog把所有博客都整理到简书上,这是一个自定义view
纠结了很久网上各种找也没找到效果差不多,索性就自己自定义了一个,分享一下。
很多人可能用过ProgressWheel这个第三方的progressbar但是它的尾部没有圆圈,那就按照它来改写吧:先讲下我的思路,我花了四个圆圈,同一个圆心这样的话只要半径不同就可以勾勒出不同的区域显示不同的颜色,最后的那个bar的颜色就直接按照弧度来划,下面上代码。
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.text.Html;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
/**
* Created by Administrator on 2016/6/7.
*/
public class MyProgressBar extends View {
//Sizes (with defaults)
private int layoutHeight = 0;
private int layoutWidth = 0;
//Padding (with defaults)
private int paddingTop = 5;
private int paddingBottom = 5;
private int paddingLeft = 5;
private int paddingRight = 5;
private String[] splitText = {"测试"};
private RectF one_rectf = new RectF();
private RectF two_rectf = new RectF();
private RectF three_rectf = new RectF();
private RectF four_rectf = new RectF();
private RectF bar_rectf = new RectF();
private int bar_color = 0xFFFEA049;
private int rim_color = 0xFFD9D9D9;
private int three_color = 0xFFFFDBB9;
private int four_color = 0xFFFEA049;
//Paints
private Paint barPaint = new Paint();
private Paint onePaint = new Paint();
private Paint twoPaint = new Paint();
private Paint threePaint = new Paint();
private Paint fourPaint = new Paint();
private Paint ciclePaint = new Paint();
private Paint textPaint = new Paint();
private float progress = 0f;
public MyProgressBar(Context context) {
super(context);
}
public MyProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
/*
* When this is called, make the view square.
*onmeasure方法是ProgressWheel的我没有动,我看主要的意思就是在不算上padding的时候把这个view弄成一个正方形
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// The first thing that happen is that we call the superclass
// implementation of onMeasure. The reason for that is that measuring
// can be quite a complex process and calling the super method is a
// convenient way to get most of this complexity handled.
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// We can’t use getWidth() or getHight() here. During the measuring
// pass the view has not gotten its final size yet (this happens first
// at the start of the layout pass) so we have to use getMeasuredWidth()
// and getMeasuredHeight().
int size = 0;
int width = getMeasuredWidth();
int height = getMeasuredHeight();
int widthWithoutPadding = width - getPaddingLeft() - getPaddingRight();
int heightWithoutPadding = height - getPaddingTop() - getPaddingBottom();
// Finally we have some simple logic that calculates the size of the view
// and calls setMeasuredDimension() to set that size.
// Before we compare the width and height of the view, we remove the padding,
// and when we set the dimension we add it back again. Now the actual content
// of the view will be square, but, depending on the padding, the total dimensions
// of the view might not be.
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (heightMode != MeasureSpec.UNSPECIFIED && widthMode != MeasureSpec.UNSPECIFIED) {
if (widthWithoutPadding > heightWithoutPadding) {
size = heightWithoutPadding;
} else {
size = widthWithoutPadding;
}
} else {
size = Math.max(heightWithoutPadding, widthWithoutPadding);
}
// If you override onMeasure() you have to call setMeasuredDimension().
// This is how you report back the measured size. If you don’t call
// setMeasuredDimension() the parent will throw an exception and your
// application will crash.
// We are calling the onMeasure() method of the superclass so we don’t
// actually need to call setMeasuredDimension() since that takes care
// of that. However, the purpose with overriding onMeasure() was to
// change the default behaviour and to do that we need to call
// setMeasuredDimension() with our own values.
setMeasuredDimension(
size + getPaddingLeft() + getPaddingRight(),
size + getPaddingTop() + getPaddingBottom());
}
//这个方法是当view的size变化的时候调用
@Override
protected void onSizeChanged(int newWidth, int newHeight, int oldWidth, int oldHeight) {
super.onSizeChanged(newWidth, newHeight, oldWidth, oldHeight);
layoutWidth = newWidth;
layoutHeight = newHeight;
setupBounds();
setupPaints();
invalidate();
}
private void setupPaints() {
barPaint.setColor(bar_color);
barPaint.setAntiAlias(true);
barPaint.setStyle(Paint.Style.STROKE);
barPaint.setStrokeWidth(10);
onePaint.setColor(rim_color);
onePaint.setAntiAlias(true);
onePaint.setStyle(Paint.Style.FILL);
// onePaint.setStrokeWidth(10);
twoPaint.setColor(Color.WHITE);
twoPaint.setAntiAlias(true);
twoPaint.setStyle(Paint.Style.FILL);
// twoPaint.setStrokeWidth(10);
threePaint.setColor(three_color);
threePaint.setAntiAlias(true);
threePaint.setStyle(Paint.Style.FILL);
// threePaint.setStrokeWidth(10);
fourPaint.setColor(four_color);
fourPaint.setAntiAlias(true);
fourPaint.setStyle(Paint.Style.FILL);
// fourPaint.setStrokeWidth(10);
ciclePaint.setColor(four_color);
ciclePaint.setAntiAlias(true);
ciclePaint.setStyle(Paint.Style.FILL);
textPaint.setColor(Color.WHITE);
textPaint.setAntiAlias(true);
textPaint.setStyle(Paint.Style.FILL);
textPaint.setTextSize(40);
}
private void setupBounds() {
one_rectf = new RectF(paddingLeft + 10, paddingTop + 10, layoutWidth - paddingRight - 10, layoutHeight - paddingBottom - 10);
two_rectf = new RectF(paddingLeft + 20, paddingTop + 20, layoutWidth - paddingRight - 20, layoutHeight - paddingBottom - 20);
three_rectf = new RectF(paddingLeft + 60, paddingTop + 60, layoutWidth - paddingRight - 60, layoutHeight - paddingBottom - 60);
four_rectf = new RectF(paddingLeft + 90, paddingTop + 90, layoutWidth - paddingRight - 90, layoutHeight - paddingBottom - 90);
bar_rectf = new RectF(paddingLeft + 15, paddingTop + 15, layoutWidth - paddingRight - 15, layoutHeight - paddingBottom - 15);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawArc(one_rectf, 360, 360, true, onePaint);
canvas.drawArc(two_rectf, 360, 360, false, twoPaint);
canvas.drawArc(three_rectf, 360, 360, false, threePaint);
canvas.drawArc(four_rectf, 360, 360, false, fourPaint);
canvas.drawArc(bar_rectf, -90, (((progress / 100f)) * 360f), false, barPaint);
float reduin = one_rectf.centerX() - paddingLeft;
for (String line : splitText) {
float horizontalTextOffset = textPaint.measureText(line) / 2;
canvas.drawText(
line + "\n",
layoutWidth / 2 - horizontalTextOffset,
layoutHeight / 2,
textPaint);
}
canvas.save();
canvas.rotate(((progress / 100f)) * 360f, one_rectf.centerX(), one_rectf.centerY());
canvas.drawCircle((float) (one_rectf.centerX()), (float) (one_rectf.centerY() - reduin + 15), 20, ciclePaint);
}
/**
* Set the progress to a specific value
*/
public void setProgress(float i) {
// isSpinning = false;
progress = (float) i;
postInvalidate();
}
}
下面就是xml里面的内容:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff">
<www.prograssbar.com.MyProgressBar
android:id="@+id/prograssbar"
android:layout_width="200dp"
android:layout_height="200dp" />
</RelativeLayout>
下面是activity里面的内容:
import android.animation.ValueAnimator;
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
private MyProgressBar progressWheel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressbar= (MyProgressBar) findViewById(R.id.prograssbar);
//添加一个属性动画,如果对属性动画不是太了解的可以阅读鸿神的博客[](http://blog.csdn.net/lmj623565791/article/details/38067475)
ValueAnimator valueAnimator2 = ValueAnimator.ofFloat(0, 30);
valueAnimator2.setDuration(1000);
valueAnimator2.start();
valueAnimator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
progressbar.setProgress((Float) animation.getAnimatedValue());
}
});
}
}