Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android自定義ProgressView長條漸變色的進度條

android自定義ProgressView長條漸變色的進度條

編輯:關於Android編程

最近在公司,項目不是很忙了,偶爾看見一個兄台在CSDN求助,幫忙要一個自定義的漸變色進度條,我當時看了一下進度條,感覺挺漂亮的,就嘗試的去自定義view實現了一個,廢話不說,先上圖吧!
\

這個自定義的view,完全脫離了android自帶的ProgressView,並且沒使用一張圖片,這樣就能更好的降低程序代碼上的耦合性!

下面我貼出代碼 ,大概講解一下實現思路吧!
package com.spring.progressview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;

/***
 * 自定義進度條
 * @author spring sky
 * Email:[email protected]
 * 創建時間:2014-1-6下午3:28:51
 */
public class SpringProgressView extends View {
	
	/**分段顏色*/
	private static final int[] SECTION_COLORS = {Color.GREEN,Color.YELLOW,Color.RED};
	/**進度條最大值*/
	private float maxCount;
	/**進度條當前值*/
	private float currentCount;
	/**畫筆*/
	private Paint mPaint;
	private int mWidth,mHeight;
	
	public SpringProgressView(Context context, AttributeSet attrs,
			int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		initView(context);
	}

	public SpringProgressView(Context context, AttributeSet attrs) {
		super(context, attrs);
		initView(context);
	}

	public SpringProgressView(Context context) {
		super(context);
		initView(context);
	}
	
	private void initView(Context context) {
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		mPaint = new Paint();
		mPaint.setAntiAlias(true);
		int round = mHeight/2;
		System.out.println("max="+maxCount + "  current="+currentCount);
		mPaint.setColor(Color.rgb(71, 76, 80));
		RectF rectBg = new RectF(0, 0, mWidth, mHeight);
		canvas.drawRoundRect(rectBg, round, round, mPaint);
		mPaint.setColor(Color.BLACK);
		RectF rectBlackBg = new RectF(2, 2, mWidth-2, mHeight-2);
		canvas.drawRoundRect(rectBlackBg, round, round, mPaint);
		
		float section = currentCount/maxCount;
		RectF rectProgressBg = new RectF(3, 3, (mWidth-3)*section, mHeight-3);
		if(section <= 1.0f/3.0f){
			if(section != 0.0f){
				mPaint.setColor(SECTION_COLORS[0]);
			}else{
				mPaint.setColor(Color.TRANSPARENT);
			}
		}else{
			int count = (section <= 1.0f/3.0f*2 ) ? 2 : 3;
			int[] colors = new int[count];
			System.arraycopy(SECTION_COLORS, 0, colors, 0, count);
			float[] positions = new float[count];
			if(count == 2){
				positions[0] = 0.0f;
				positions[1] = 1.0f-positions[0];
			}else{
				positions[0] = 0.0f;
				positions[1] = (maxCount/3)/currentCount;
				positions[2] = 1.0f-positions[0]*2;
			}
			positions[positions.length-1] = 1.0f;
			LinearGradient shader = new LinearGradient(3, 3, (mWidth-3)*section, mHeight-3, colors,null, Shader.TileMode.MIRROR);
			mPaint.setShader(shader);
		}
		canvas.drawRoundRect(rectProgressBg, round, round, mPaint);
	}
	
	private int dipToPx(int dip) {
		float scale = getContext().getResources().getDisplayMetrics().density;
		return (int) (dip * scale + 0.5f * (dip >= 0 ? 1 : -1));
	}
	
	/***
	 * 設置最大的進度值
	 * @param maxCount
	 */
	public void setMaxCount(float maxCount) {
		this.maxCount = maxCount;
	}
	
	/***
	 * 設置當前的進度值
	 * @param currentCount
	 */
	public void setCurrentCount(float currentCount) {
		this.currentCount = currentCount > maxCount ? maxCount : currentCount;
		invalidate();
	}
	
	public float getMaxCount() {
		return maxCount;
	}
	
	public float getCurrentCount() {
		return currentCount;
	}
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
		int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
		int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
		int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
		if (widthSpecMode == MeasureSpec.EXACTLY || widthSpecMode == MeasureSpec.AT_MOST) {
			mWidth = widthSpecSize;
		} else {
			mWidth = 0;
		}
		if (heightSpecMode == MeasureSpec.AT_MOST || heightSpecMode == MeasureSpec.UNSPECIFIED) {
			mHeight = dipToPx(15);
		} else {
			mHeight = heightSpecSize;
		}
		setMeasuredDimension(mWidth, mHeight);
	}
	

	
}


以上代碼就是該控件的全部核心代碼了
具體思路:
1.進度條,其實就是一個最大值和最小值的比例值,這個比例就是 當前值/最大值;
2.自定義的圓角問題,只要還是用到了Canvar的畫板的drawRoundRect ;
3.漸變色:LinearGradient對象渲染,具體渲染的比例要自己計算,目前我的程序提供3中顏色渲染,具體規則是:
(1)當進度條占最大值的三分之一以下,則提供一種顏色
(2)當最大值超過三分之一話,就區分是否超過三分之二,如果超過則用三種,否則用兩種顏色,因為三種顏色各占總進度條的三分之一,這是一個初中數據的問題,自己慢慢畫圖吧!
4.怎麼把進度條放在一個有圓角背景的上面,這個就是繪制兩個圓角長方形:第一個作為背景,第二個作為進度條的實體,具體第二個進度的實體占多長,就是當前 currentCount/maxCount*自定義View的長度 ;



其他的,沒啥技術難點了,做這種自定義控件,最重要的是,自定要根據人家的效果圖,看懂實現思路,具體代碼簡歷在思路上的,否則只會紙上談兵!如果看不懂,就要多畫圖,具體的一步步計算,天長地久,也就能“練”出來了!

下面提供一個demo下載地址:SpringProgressDemo





  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved