软件编程
位置:首页>> 软件编程>> Android编程>> Android实现多段颜色进度条效果

Android实现多段颜色进度条效果

作者:淡定的程序猿  发布时间:2023-09-30 22:07:51 

标签:Android,进度条

多段颜色的进度条实现思路,供大家参考,具体内容如下

这个进度条其实相对简单.
这里可以把需要绘制的简单分为两个部分

1.灰色背景部分
2.多段颜色的进度部分

考虑到实际绘制中,分段部分不太容易根据进度值进行动态绘制.
故把多段颜色部分作为背景进行绘制,实际的灰色部分根据进度值变化,达到多段颜色部分进度变化的效果.

实现步骤

1.自定义View 来绘制进度条
2.定义背景及进度条绘制所需的画笔


private Paint backgroundPaint, progressPaint, linePaint;//背景和进度条画笔

3.定义不同颜色区域的矩阵数组(这里将进度分为多个色块)
4.定义颜色数组,以及所占比例的数组.后面根据比例和颜色进行绘制


private Rect progressRect = new Rect();//进度条;
private Rect backgroundRects[];//背景矩形区域
private float weights[];//每个区域的权重
private int colors[];//颜色

5.定义进度值,监听等杂项.


private float progress = 10, maxProgress = 100;//进度和最大进度
private OnProgressChangeListener listener;

6.在draw方法中进行绘制
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;//计算下一个的开始位置
  canvas.drawRect(rect, backgroundPaint);//绘制矩形
}

8.进度条及分割线的绘制


progressRect.set(0, 0, progressX, getHeight());//设置进度条区域
canvas.drawRect(progressRect, progressPaint);//绘制进度条
for (int i = 0, lineX = 0; i < colors.length; i++) {
  int width = (int) (getWidthForWeight(weights[i], totalWeight));
  //绘制矩形块之间的分割线
  lineX = lineX + width;
  if (lineX < progressX) {//给已经走过了的区域画上竖线
     canvas.drawLine(lineX, 0, lineX, getHeight(), linePaint);
   }
}

最后看看实现的效果图

Android实现多段颜色进度条效果

完整代码


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;

/**
* 多段颜色的进度条
* Created by WQ on 2017/7/11.
*/

public class MultistageProgress extends View {

private Paint backgroundPaint, progressPaint, linePaint;//背景和进度条画笔
 private Rect progressRect = new Rect();//进度条;
 private Rect backgroundRects[];//背景矩形区域
 private float weights[];//每个区域的权重
 private int colors[];//颜色
 private float totalWeight;//总的权重
 public static final int DEF_COLORS[];//默认背景颜色数组
 public static final float DEF_WEIGHTS[];//每段对应的权重
 private float progress = 10, maxProgress = 100;//进度和最大进度
 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);

}

/**
  * 设置进度条颜色
  *
  * @param color
  */
 public void setProgressColor(int color) {
   progressPaint.setColor(color);
 }

/**
  * 设置每一段的颜色以及对应的权重
  *
  * @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;//计算下一个的开始位置
     canvas.drawRect(rect, backgroundPaint);//绘制矩形
   }
   progressRect.set(0, 0, progressX, getHeight());//设置进度条区域
   canvas.drawRect(progressRect, progressPaint);//绘制进度条
   for (int i = 0, lineX = 0; i < colors.length; i++) {
     int width = (int) (getWidthForWeight(weights[i], totalWeight));
     //绘制矩形块之间的分割线
     lineX = lineX + width;
     if (lineX < progressX) {//给已经走过了的区域画上竖线
       canvas.drawLine(lineX, 0, lineX, getHeight(), linePaint);
     }
   }

}

/**
  * 根据权重获取对应的宽度
  *
  * @param weight
  * @param totalWeight
  * @return
  */
 public float getWidthForWeight(float weight, float totalWeight) {
   return getWidth() * (weight / totalWeight) + 0.5f;
 }

/**
  * 根据根据权重在数组中的索引获取对应的位置
  *
  * @param position
  * @return
  */
 public float getXForWeightPosition(int position) {
   float xPosition = 0;
   for (int i = 0; i < position; i++) {
     xPosition += getWidthForWeightPosition(i);
   }
   return xPosition;
 }

/**
  * 根据根据权重在数组中的索引获取对应的宽度
  *
  * @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(), "进度值 " + 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 {
   /**
    * 进度改变时触发
    * @param progress 进度
    * @param position 所在区间段
    */
   void onProgressChange(float progress, int position);
 }
}

来源:http://blog.csdn.net/a976112643/article/details/76523481

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com