Android實(shí)現(xiàn)多段顏色進(jìn)度條效果
多段顏色的進(jìn)度條實(shí)現(xiàn)思路,供大家參考,具體內(nèi)容如下
這個(gè)進(jìn)度條其實(shí)相對(duì)簡(jiǎn)單.
這里可以把需要繪制的簡(jiǎn)單分為兩個(gè)部分
1.灰色背景部分
2.多段顏色的進(jìn)度部分
考慮到實(shí)際繪制中,分段部分不太容易根據(jù)進(jìn)度值進(jìn)行動(dòng)態(tài)繪制.
故把多段顏色部分作為背景進(jìn)行繪制,實(shí)際的灰色部分根據(jù)進(jìn)度值變化,達(dá)到多段顏色部分進(jìn)度變化的效果.
實(shí)現(xiàn)步驟
1.自定義View 來(lái)繪制進(jìn)度條
2.定義背景及進(jìn)度條繪制所需的畫筆
private Paint backgroundPaint, progressPaint, linePaint;//背景和進(jìn)度條畫筆
3.定義不同顏色區(qū)域的矩陣數(shù)組(這里將進(jìn)度分為多個(gè)色塊)
4.定義顏色數(shù)組,以及所占比例的數(shù)組.后面根據(jù)比例和顏色進(jìn)行繪制
private Rect progressRect = new Rect();//進(jìn)度條; private Rect backgroundRects[];//背景矩形區(qū)域 private float weights[];//每個(gè)區(qū)域的權(quán)重 private int colors[];//顏色
5.定義進(jìn)度值,監(jiān)聽等雜項(xiàng).
private float progress = 10, maxProgress = 100;//進(jìn)度和最大進(jìn)度 private OnProgressChangeListener listener;
6.在draw方法中進(jìn)行繪制
7.背景色塊的繪制
//繪制背景顏色塊
int x = 0, y = getHeight();
int progressX = (int) getWidthForWeight(progress, maxProgress);
for (int i = 0; i < colors.length; i++) {
Rect rect = backgroundRects[i];
backgroundPaint.setColor(colors[i]);
int width = (int) (getWidthForWeight(weights[i], totalWeight));
rect.set(x, 0, x + width, y);
x += width;//計(jì)算下一個(gè)的開始位置
canvas.drawRect(rect, backgroundPaint);//繪制矩形
}
8.進(jìn)度條及分割線的繪制
progressRect.set(0, 0, progressX, getHeight());//設(shè)置進(jìn)度條區(qū)域
canvas.drawRect(progressRect, progressPaint);//繪制進(jìn)度條
for (int i = 0, lineX = 0; i < colors.length; i++) {
int width = (int) (getWidthForWeight(weights[i], totalWeight));
//繪制矩形塊之間的分割線
lineX = lineX + width;
if (lineX < progressX) {//給已經(jīng)走過(guò)了的區(qū)域畫上豎線
canvas.drawLine(lineX, 0, lineX, getHeight(), linePaint);
}
}
最后看看實(shí)現(xiàn)的效果圖

完整代碼
package com.wq.widget;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.LinearInterpolator;
/**
* 多段顏色的進(jìn)度條
* Created by WQ on 2017/7/11.
*/
public class MultistageProgress extends View {
private Paint backgroundPaint, progressPaint, linePaint;//背景和進(jìn)度條畫筆
private Rect progressRect = new Rect();//進(jìn)度條;
private Rect backgroundRects[];//背景矩形區(qū)域
private float weights[];//每個(gè)區(qū)域的權(quán)重
private int colors[];//顏色
private float totalWeight;//總的權(quán)重
public static final int DEF_COLORS[];//默認(rèn)背景顏色數(shù)組
public static final float DEF_WEIGHTS[];//每段對(duì)應(yīng)的權(quán)重
private float progress = 10, maxProgress = 100;//進(jìn)度和最大進(jìn)度
private OnProgressChangeListener listener;
static {
DEF_COLORS = new int[]{
Color.parseColor("#00B6D0"),
Color.parseColor("#0198AE"),
Color.parseColor("#008396"),
Color.parseColor("#007196"),
Color.parseColor("#005672")
};
DEF_WEIGHTS = new float[]{
138, 35, 230, 230, 57
};
}
public float getProgress() {
return progress;
}
public void setProgress(float progress) {
this.progress = progress;
invalidate();
onProgressChange();
}
private void onProgressChange() {
if (listener != null) {
int position = 0;
int currentWidth = (int) getWidthForWeight(getProgress(), getMaxProgress());
int tmpWidth = 0;
for (int i = 0; i < weights.length; i++) {
tmpWidth += (int) getWidthForWeight(weights[i], totalWeight);
if (tmpWidth >= currentWidth) {
position = i;
break;
}
}
listener.onProgressChange(getProgress(), position);
}
}
public float getMaxProgress() {
return maxProgress;
}
public void setMaxProgress(float maxProgress) {
this.maxProgress = maxProgress;
invalidate();
}
public OnProgressChangeListener getProgressChangeListener() {
return listener;
}
public void setProgressChangeListener(OnProgressChangeListener listener) {
this.listener = listener;
}
public MultistageProgress(Context context) {
super(context);
init();
}
public MultistageProgress(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MultistageProgress(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public MultistageProgress(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
public void init() {
backgroundPaint = new Paint();
backgroundPaint.setStyle(Paint.Style.FILL_AND_STROKE);
backgroundPaint.setColor(Color.RED);
progressPaint = new Paint();
progressPaint.setStyle(Paint.Style.FILL_AND_STROKE);
progressPaint.setColor(Color.parseColor("#d9d9d9"));
linePaint = new Paint();
linePaint.setStyle(Paint.Style.FILL_AND_STROKE);
linePaint.setColor(Color.parseColor("#e7eaf0"));
linePaint.setStrokeWidth(2);
setColors(DEF_COLORS, DEF_WEIGHTS);
}
/**
* 設(shè)置進(jìn)度條顏色
*
* @param color
*/
public void setProgressColor(int color) {
progressPaint.setColor(color);
}
/**
* 設(shè)置每一段的顏色以及對(duì)應(yīng)的權(quán)重
*
* @param colors
* @param weights
*/
public void setColors(int[] colors, float weights[]) {
if (colors == null || weights == null) {
throw new NullPointerException("colors And weights must be not null");
}
if (colors.length != weights.length) {
throw new IllegalArgumentException("colors And weights length must be same");
}
backgroundRects = new Rect[colors.length];
this.colors = colors;
this.weights = weights;
totalWeight = 0;
for (int i = 0; i < weights.length; i++) {
totalWeight += weights[i];
backgroundRects[i] = new Rect();
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (backgroundRects == null) {
return;
}
if (maxProgress <= 0) {
maxProgress = getWidth();
}
//繪制背景顏色塊
int x = 0, y = getHeight();
int progressX = (int) getWidthForWeight(progress, maxProgress);
for (int i = 0; i < colors.length; i++) {
Rect rect = backgroundRects[i];
backgroundPaint.setColor(colors[i]);
int width = (int) (getWidthForWeight(weights[i], totalWeight));
rect.set(x, 0, x + width, y);
x += width;//計(jì)算下一個(gè)的開始位置
canvas.drawRect(rect, backgroundPaint);//繪制矩形
}
progressRect.set(0, 0, progressX, getHeight());//設(shè)置進(jìn)度條區(qū)域
canvas.drawRect(progressRect, progressPaint);//繪制進(jìn)度條
for (int i = 0, lineX = 0; i < colors.length; i++) {
int width = (int) (getWidthForWeight(weights[i], totalWeight));
//繪制矩形塊之間的分割線
lineX = lineX + width;
if (lineX < progressX) {//給已經(jīng)走過(guò)了的區(qū)域畫上豎線
canvas.drawLine(lineX, 0, lineX, getHeight(), linePaint);
}
}
}
/**
* 根據(jù)權(quán)重獲取對(duì)應(yīng)的寬度
*
* @param weight
* @param totalWeight
* @return
*/
public float getWidthForWeight(float weight, float totalWeight) {
return getWidth() * (weight / totalWeight) + 0.5f;
}
/**
* 根據(jù)根據(jù)權(quán)重在數(shù)組中的索引獲取對(duì)應(yīng)的位置
*
* @param position
* @return
*/
public float getXForWeightPosition(int position) {
float xPosition = 0;
for (int i = 0; i < position; i++) {
xPosition += getWidthForWeightPosition(i);
}
return xPosition;
}
/**
* 根據(jù)根據(jù)權(quán)重在數(shù)組中的索引獲取對(duì)應(yīng)的寬度
*
* @param position
* @return
*/
public float getWidthForWeightPosition(int position) {
return getWidth() * (weights[position] / totalWeight) + 0.5f;
}
ObjectAnimator valueAnimator;
public void autoChange(float startProgress, float endProgress, long changeTime) {
if (valueAnimator != null && valueAnimator.isRunning()) return;
setProgress((int) startProgress);
setMaxProgress((int) endProgress);
valueAnimator = ObjectAnimator.ofFloat(this, "progress", startProgress, endProgress);
valueAnimator.setDuration(changeTime);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
// setProgress((int) value);
Log.d(getClass().getName(), "進(jìn)度值 " + value);
}
});
valueAnimator.start();
}
public void stopChange() {
if (valueAnimator != null && valueAnimator.isRunning()) valueAnimator.cancel();
}
@Override
protected void onDetachedFromWindow() {
if (valueAnimator != null && valueAnimator.isRunning()) {
valueAnimator.cancel();
}
super.onDetachedFromWindow();
}
public interface OnProgressChangeListener {
/**
* 進(jìn)度改變時(shí)觸發(fā)
* @param progress 進(jìn)度
* @param position 所在區(qū)間段
*/
void onProgressChange(float progress, int position);
}
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android 七種進(jìn)度條的樣式
- Android中實(shí)現(xiàn)Webview頂部帶進(jìn)度條的方法
- android自定義進(jìn)度條漸變色View的實(shí)例代碼
- Android文件下載進(jìn)度條的實(shí)現(xiàn)代碼
- android ListView和ProgressBar(進(jìn)度條控件)的使用方法
- Android中自定義進(jìn)度條詳解
- 實(shí)例詳解Android自定義ProgressDialog進(jìn)度條對(duì)話框的實(shí)現(xiàn)
- Android三種方式實(shí)現(xiàn)ProgressBar自定義圓形進(jìn)度條
- Android ProgressBar進(jìn)度條和ProgressDialog進(jìn)度框的展示DEMO
- Android ProgressBar進(jìn)度條使用詳解
相關(guān)文章
Android GuideView實(shí)現(xiàn)首次登陸引導(dǎo)
這篇文章主要為大家詳細(xì)介紹了Android GuideView實(shí)現(xiàn)首次登陸引導(dǎo),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-03-03
Android studio 下JNI編程實(shí)例并生成so庫(kù)的實(shí)現(xiàn)代碼
這篇文章主要介紹了Android studio 下JNI編程實(shí)例并生成so庫(kù),需要的朋友可以參考下2017-09-09
Android popupwindow簡(jiǎn)單使用方法介紹
這篇文章主要為大家詳細(xì)介紹了Android popupwindow簡(jiǎn)單使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12
Android下通過(guò)httpClient發(fā)送GET和POST請(qǐng)求的實(shí)例代碼
這篇文章介紹了Android下通過(guò)httpClient發(fā)送GET和POST請(qǐng)求的實(shí)例代碼,有需要的朋友可以參考一下2013-08-08
Android之利用EventBus發(fā)送消息傳遞示例
本篇文章主要介紹了Android之利用EventBus進(jìn)行消息傳遞示例。EventBus是一款針對(duì)Android優(yōu)化的發(fā)布/訂閱事件總線,非常具有實(shí)用價(jià)值,需要的朋友可以參考下。2017-02-02
android實(shí)現(xiàn)播放網(wǎng)絡(luò)視頻
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)播放網(wǎng)絡(luò)視頻,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-04-04
Android 斷點(diǎn)續(xù)傳原理以及實(shí)現(xiàn)
這篇文章主要介紹了Android 斷點(diǎn)續(xù)傳原理以及實(shí)現(xiàn)的相關(guān)資料,這里對(duì)斷點(diǎn)續(xù)傳原理進(jìn)行了詳細(xì)介紹,需要的朋友可以參考下2016-12-12

