1. 程式人生 > >一個簡單的自定義View,仿圓形進度條

一個簡單的自定義View,仿圓形進度條

一個很簡單的小例子,,整理一下

效果圖


上程式碼,程式碼中應該註釋很清楚了,就不再贅述,是模仿洋大神寫的,然後自己又加了一點兒自己的理解。

程式碼如下

package com.example.roundview;


import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;

public class RoundView extends View {
	private int roundWidth;
	private int speed;//此處為自定義的速度,簡單點,speed是幾,幾秒轉完一圈
	private Paint mPaint;
	private int process;
	private int processColor = Color.BLUE;
	private RectF mRectf;
	private TextPaint textPaint;
	private Rect textRect;
	public RoundView(Context context) {
		this(context, null);
	}

	public RoundView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public RoundView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		setBackgroundColor(Color.YELLOW);
		initAttr(context, attrs);
		mPaint = new Paint();
		mRectf = new RectF();
		textRect = new Rect();
		textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
		textPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 12, getResources().getDisplayMetrics()));
		textPaint.setColor(Color.BLACK);
		textPaint.setStyle(Paint.Style.FILL);
		startRun();
	}
	//開始繪製
	private void startRun() {
		final int angle = 360/speed;
		new Thread(){
			public void run() {
				while(true){
					process+=angle;
					if(process == 360){
						process = 0;
						processColor = Color.GREEN;
					}
					postInvalidate();
					try {
						sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			};
		}.start();
	}

	private void initAttr(Context context, AttributeSet attrs) {
		TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.RoundView);
		roundWidth = array.getDimensionPixelSize(R.styleable.RoundView_roundWidth, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, getResources().getDisplayMetrics()));
		speed = array.getInt(R.styleable.RoundView_speed, 6);
		array.recycle();
	}
	

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		setMeasuredDimension(measureWidth(widthMeasureSpec),measureHeight(heightMeasureSpec));
		
	}
	private int measureHeight(int heightMeasureSpec) {
		int height = 0;
		int minHeight = 154;//定義最小的高度為154,相當於layout_height為wrap_content的時候,高度為154px
		int specMode = MeasureSpec.getMode(heightMeasureSpec);
		int specSize = MeasureSpec.getSize(heightMeasureSpec);
		switch(specMode){
			case MeasureSpec.EXACTLY:
				height = specSize<minHeight?minHeight:specSize;
				break;
			case MeasureSpec.AT_MOST:
				height = getPaddingTop()+getPaddingBottom()+minHeight;
				break;
			case MeasureSpec.UNSPECIFIED://當最外層是scrollview的時候,是這種模式
				height = getPaddingTop()+getPaddingBottom()+minHeight;
				break;
			
		}
		return height;
	}

	private int measureWidth(int widthMeasureSpec) {
		int width = 0;
		int minWidth = 154;//定義最小的寬度為154,相當於layout_width為wrap_content的時候,寬度為154px
		int specMode = MeasureSpec.getMode(widthMeasureSpec);
		int specSize = MeasureSpec.getSize(widthMeasureSpec);
		switch(specMode){
			case MeasureSpec.EXACTLY:
				width = specSize<minWidth?minWidth:specSize;//要是小於56的話不怎麼好看,當然可以自定義
				break;
			case MeasureSpec.AT_MOST:
				width = getPaddingLeft()+getPaddingRight()+minWidth;
				break;
			case MeasureSpec.UNSPECIFIED:
				width = getPaddingLeft()+getPaddingRight()+minWidth;
				break;
			
		}
		return width;
	}

	@Override
	protected void onDraw(Canvas canvas) {
		//繪製外邊那個圓環
		int center = getMeasuredWidth()/2;
		int radius = center-roundWidth/2-getPaddingLeft();//這個是畫筆的筆芯位於圓環的中間
		Log.i("TAG","radius"+radius);
		mPaint.setAntiAlias(true);
		mPaint.setColor(Color.RED);
		mPaint.setStrokeWidth(roundWidth);
		mPaint.setStyle(Paint.Style.STROKE);
		canvas.drawCircle(center, center, radius, mPaint);
		//更具進度繪製進度
		mPaint.setColor(processColor);
		mRectf.left = roundWidth/2+getPaddingLeft();
		mRectf.top = roundWidth/2+getPaddingTop();
		mRectf.right = center+radius;
		mRectf.bottom = center+radius;
		canvas.drawArc(mRectf, -90, process, false, mPaint);
		//繪製文字百分比		
		String percent = String.format("%d%%", Math.round(process*1.0f/360*100));
		textPaint.getTextBounds(percent, 0, percent.length(), textRect);
		canvas.drawText(percent, center -textRect.width()/2, center+textRect.height()/2, textPaint);
	}
}