首页 > 代码库 > 【安卓笔记】扁平化的ProgressBar-----ProgressWheel

【安卓笔记】扁平化的ProgressBar-----ProgressWheel

ProgressWheel是github上一个开源的项目,为开发者提供一个扁平化的ProgressBar,并可以对其进行深度定制。效果如下:


下面介绍使用方式:
1.下面是ProgressWheel源码,拷到项目下。
package com.example.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.graphics.Shader;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;
import com.example.progresswheeldemo.R;
/**
 * An indicator of progress, similar to Android's ProgressBar. Can be used in
 * 'spin mode' or 'increment mode'
 * 
 * @author Todd Davies
 *         <p/>
 *         Licensed under the Creative Commons Attribution 3.0 license see:
 *         http://creativecommons.org/licenses/by/3.0/
 */
public class ProgressWheel extends View
{
	// Sizes (with defaults)
	private int layout_height = 0;
	private int layout_width = 0;
	private int fullRadius = 100;
	private int circleRadius = 80;
	private int barLength = 60;
	private int barWidth = 20;
	private int rimWidth = 20;
	private int textSize = 20;
	private float contourSize = 0;
	// Padding (with defaults)
	private int paddingTop = 5;
	private int paddingBottom = 5;
	private int paddingLeft = 5;
	private int paddingRight = 5;
	// Colors (with defaults)
	private int barColor = 0xAA000000;
	private int contourColor = 0xAA000000;
	private int circleColor = 0x00000000;
	private int rimColor = 0xAADDDDDD;
	private int textColor = 0xFF000000;
	// Paints
	private Paint barPaint = new Paint();
	private Paint circlePaint = new Paint();
	private Paint rimPaint = new Paint();
	private Paint textPaint = new Paint();
	private Paint contourPaint = new Paint();
	// Rectangles
	@SuppressWarnings("unused")
	private RectF rectBounds = new RectF();
	private RectF circleBounds = new RectF();
	private RectF circleOuterContour = new RectF();
	private RectF circleInnerContour = new RectF();
	// Animation
	// The amount of pixels to move the bar by on each draw
	private int spinSpeed = 2;
	// The number of milliseconds to wait inbetween each draw
	private int delayMillis = 0;
	private Handler spinHandler = new Handler()
	{
		/**
		 * This is the code that will increment the progress variable and so
		 * spin the wheel
		 */
		@Override
		public void handleMessage(Message msg)
		{
			invalidate();
			if (isSpinning)
			{
				progress += spinSpeed;
				if (progress > 360)
				{
					progress = 0;
				}
				spinHandler.sendEmptyMessageDelayed(0, delayMillis);
			}
			// super.handleMessage(msg);
		}
	};
	int progress = 0;
	boolean isSpinning = false;
	// Other
	private String text = "";
	private String[] splitText =
	{};
	/**
	 * The constructor for the ProgressWheel
	 * 
	 * @param context
	 * @param attrs
	 */
	public ProgressWheel(Context context, AttributeSet attrs)
	{
		super(context, attrs);
		parseAttributes(context.obtainStyledAttributes(attrs,
				R.styleable.ProgressWheel));
	}
	// ----------------------------------
	// Setting up stuff
	// ----------------------------------
	/*
	 * When this is called, make the view square. From:
	 * http://www.jayway.com/2012
	 * /12/12/creating-custom-android-views-part-4-measuring
	 * -and-how-to-force-a-view-to-be-square/
	 */
	@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鈥檛 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 heigthWithoutPadding = 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.
		if (widthWithoutPadding > heigthWithoutPadding)
		{
			size = heigthWithoutPadding;
		} else
		{
			size = widthWithoutPadding;
		}
		// If you override onMeasure() you have to call setMeasuredDimension().
		// This is how you report back the measured size. If you don鈥檛 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鈥檛
		// 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());
	}
	/**
	 * Use onSizeChanged instead of onAttachedToWindow to get the dimensions of
	 * the view, because this method is called after measuring the dimensions of
	 * MATCH_PARENT & WRAP_CONTENT. Use this dimensions to setup the bounds and
	 * paints.
	 */
	@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();
	}
	/**
	 * Set the properties of the paints we're using to draw the 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);
	}
	/**
	 * Set the bounds of the component
	 */
	private void setupBounds()
	{
		// Width should equal to Height, find the min value to steup the circle
		int minValue = http://www.mamicode.com/Math.min(layout_width, layout_height);>2.将如下的属性文件拷到attrs.xml中:

<?xml version="1.0" encoding="utf-8"?>
<resources>
	<declare-styleable name="ProgressWheel">
        <attr name="text" format="string" />
        <attr name="textColor" format="color" />
        <attr name="textSize" format="dimension" />
        <attr name="barColor" format="color" /><!-- 进度条颜色 -->
        <attr name="rimColor" format="color" /><!-- 默认轮廓颜色 -->
        <attr name="rimWidth" format="dimension" />
        <attr name="spinSpeed" format="dimension" />
        <attr name="delayMillis" format="integer" />
        <attr name="circleColor" format="color" /><!-- 圆圈内部的颜色 -->
        <attr name="radius" format="dimension" />
        <attr name="barWidth" format="dimension" /><!-- 进度条宽度 -->
        <attr name="barLength" format="dimension" /><!-- 进度条长度(即进度条走过的长度) -->
        <attr name="contourColor" format="color"/><!-- 控制外边缘颜色 -->
        <attr name="contourSize" format="dimension"/>
    </declare-styleable>   
</resources>

3.在布局文件中声明控件:
注:首先你得加上命名空间:
xmlns:ProgressWheel="http://schemas.android.com/apk/res/包名"
声明控件:

<com.example.view.ProgressWheel
        android:id="@+id/pw_spinner"
        android:layout_width="180dp"
        android:layout_height="180dp"
        android:layout_centerInParent="true"
        ProgressWheel:barColor="#0097D6"
        ProgressWheel:barLength="160dp"
        ProgressWheel:barWidth="15dp"
        ProgressWheel:rimColor="#330097D6"
        ProgressWheel:rimWidth="15dp"
        ProgressWheel:text="wait..."
        ProgressWheel:contourColor="#330097D6"
        ProgressWheel:textColor="#222"

4.在代码中使用控件:

wheel = (ProgressWheel) findViewById(R.id.pw_spinner);//找到控件
		wheel.setProgress(180);//设置进度
		wheel.incrementProgress();//增加进度
		wheel.spin();//使控件开始旋转
		wheel.stopSpinning();//停止旋转








【安卓笔记】扁平化的ProgressBar-----ProgressWheel