本文展示了如何在 Android 中通过继承 View 类实现自定义的节点进度条组件。核心逻辑包括初始化资源、计算节点位置与偏移量、在 Canvas 上绘制空心圆、实心圆及连接进度条,并根据当前进度动态更新节点颜色与进度条长度。
核心代码实现
package utils.android.view.lxz;
import java.util.ArrayList;
import java.util.List;
import com.community.custom.android.R;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
/**
* 2015-1-24
* 小林爱
*/
public class NodeProgressBar extends View implements Runnable {
private float dn = 1f;
DisplayMetrics metrics;
{
metrics = new DisplayMetrics();
((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(metrics);
dn = 1 * 3 / metrics.density;
}
/**读取空进度条图片*/
BitmapDrawable db_empty;
viewWidth;
viewHeight;
List<BitmapDrawable> list_whitecircle;
List<BitmapDrawable> list_bluecircle;
BitmapDrawable db_blue;
;
String[] textArr = []{, , , };
textArr.length;
;
() ( / dn);
() ( / dn);
() ( / dn);
() (- / dn);
() (- / dn);
BitmapDrawable db_blue_half_circle;
();
() ( / dn);
() ( / dn);
() ( / dn);
() ( / dn);
;
;
() ( / dn);
maxProgressWidth;
() ( / dn);
String[] getTextArr() {
textArr;
}
{
.textArr = textArr;
count = textArr.length;
init();
.post( () {
{
viewWidth = NodeProgressBar..getWidth();
viewHeight = NodeProgressBar..getHeight();
maxProgressWidth = viewWidth - r_white - offX * ;
invalidate();
}
});
}
{
(context);
init();
}
{
(context, attrs);
init();
}
{
ratio = i / ;
invalidate();
}
{
.post( () {
{
progress;
(d == )
{
progress = ;
}
{
progress = () (( / ((count - ) * )) * (d - ));
}
setProgressAndIndex(progress);
}
});
}
{
(i==){
index=;
ratio=;
invalidate();
;
}
maxProgressWidth-(count-)*r_white;
k=/(count-);
index=+i/k;
(index!=count)
{
wh=*(r_white/)/()maxProgressWidth;
ratio=i%==?ratio=:wh+wh**(index-)+*(()adbProgress/()maxProgressWidth)*(i/);
}
{
ratio=;
}
invalidate();
}
{
metrics= ();
((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(metrics);
Log.d(, +metrics.density);
dn=*/metrics.density;
list_whitecircle= <BitmapDrawable>();
list_bluecircle= <BitmapDrawable>();
( ; i < count; i++) {
(
BitmapFactory.decodeResource(getResources(),
R.drawable.progress_white_circle));
list_whitecircle.add(drawable1);
(
BitmapFactory.decodeResource(getResources(),
R.drawable.progress_blue_circle));
list_bluecircle.add(drawable2);
}
db_blue_half_circle = (BitmapFactory.decodeResource(
getResources(), R.drawable.progress_blue_half_circle));
db_empty = (BitmapFactory.decodeResource(
getResources(), R.drawable.progress_white_groove));
db_blue = (BitmapFactory.decodeResource(
getResources(), R.drawable.progress_blue_groove));
.post();
}
{
viewWidth = NodeProgressBar..getWidth();
viewHeight = NodeProgressBar..getHeight();
maxProgressWidth = viewWidth - r_white-offX*;
invalidate();
}
{
.draw(canvas);
offAbs_x=()((viewWidth-maxProgressWidth)/);
canvas.drawColor(Color.TRANSPARENT);
drawRect(canvas, db_empty, viewWidth / , r_white / +offY+offWhiteRect_y, maxProgressWidth,whiteProgressHeight);
paint.setTextSize(textSize);
paint.setFakeBoldText();
( , j = list_whitecircle.size(); i < j; i++) {
list_whitecircle.get(i);
x=maxProgressWidth / (count - )* i+offAbs_x;
y=r_white/ + offWhiteCirle_y+offY;
drawCircle(canvas, db_whitecircle,x, y, r_white);
String str=textArr[i];
(i<index)
{
paint.setColor(Color.parseColor(textColor));
}
{
paint.setColor(Color.parseColor(textColorNotEnabled));
}
paint.measureText(str);
canvas.drawText(str, x-textWidht/, y+offTextY, paint);
}
drawRect(canvas, db_blue, ()
((maxProgressWidth * ratio) / )+offAbs_x ,
r_white / +offY,
() (maxProgressWidth * ratio),blueProgressHeight);
(ratio > ) {
drawRect(canvas, db_blue_half_circle,() ((maxProgressWidth * ratio) / )
+ () (maxProgressWidth * ratio) / + half_blueWidth
/ +offAbs_x, r_white / +offY, half_blueWidth,
blueProgressHeight);
}
( , j = index; i < j; i++) {
list_bluecircle.get(i);
drawCircle(canvas, db_bluecircle,
maxProgressWidth / (count - ) * i+offAbs_x, r_white/+offY, r_blue);
}
}
{
d.setBounds(x - width / , y - height / , x + width / , y + height
/ );
d.draw(canvas);
}
{
d.setBounds(x - r / , y - r / , x + r / , y + r / );
d.draw(canvas);
}
{
canvas.drawText(str, x-w/, y-h/, x+w, y+h, paint);
}
{
ratio;
}
{
.ratio = ratio;
}
{
count;
}
{
.count = count;
}
{
index;
}
{
.index = index;
}
}


