自定义进度条

6

我正在尝试创建一个看起来像下图的 ProgresBar

期望的 ProgressBar

到目前为止,我已经创建了一个扩展 ProgressBar 的对象,并且现在我正在尝试找出下一步该怎么做。

我知道我需要重写 onDraw() 方法,并使用一些逻辑来决定要填充多少个小方块,这是很容易的。

但我不知道如何获得这些小方块。我应该如何替换默认的绘制对象,以便在布局中添加自定义进度条时可以看到像图片一样的东西呢?


你只需要创建一个自定义进度Drawable,它会在级别改变时做出反应,参见Drawable.onLevelChange。 - pskink
@pskink你是在说我不需要使用进度条吗? - BloonsTowerDefence
是的,只需扩展Drawable并使用setProgressDrawable。 - pskink
好的,你需要一个ProgressBar,但不需要扩展它,只需使用自定义的Drawable即可。 - pskink
@pskink,您能提供一些代码,然后我会将其选为答案吗? - BloonsTowerDefence
首先扩展Drawable并覆盖draw()和onLevelChange()方法,在draw()中根据当前级别绘制矩形,在onLevelChange()中调用invalidateSelf()。 - pskink
1个回答

12

试试这个自定义的Drawable:

class ProgressDrawable extends Drawable {
    private static final int NUM_RECTS = 10;
    Paint mPaint = new Paint();

    @Override
    protected boolean onLevelChange(int level) {
        invalidateSelf();
        return true;
    }

    @Override
    public void draw(Canvas canvas) {
        int level = getLevel();
        Rect b = getBounds();
        float width = b.width();
        for (int i = 0; i < NUM_RECTS; i++) {
            float left = width * i / NUM_RECTS;
            float right = left + 0.9f * width / NUM_RECTS;
            mPaint.setColor((i + 1) * 10000 / NUM_RECTS <= level? 0xff888888 : 0xffbbbbbb);
            canvas.drawRect(left, b.top, right, b.bottom, mPaint);
        }
    }

    @Override
    public void setAlpha(int alpha) {
    }

    @Override
    public void setColorFilter(ColorFilter cf) {
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }
}

在 onCreate 中使用以下内容测试它:

LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);

final ProgressBar pb = new ProgressBar(this, null, android.R.attr.progressBarStyleHorizontal);
Drawable d = new ProgressDrawable();
pb.setProgressDrawable(d);
pb.setPadding(20, 20, 20, 0);
ll.addView(pb);

OnSeekBarChangeListener l = new OnSeekBarChangeListener() {
    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        int newProgress = pb.getMax() * progress / seekBar.getMax();
        Log.d(TAG, "onProgressChanged " + newProgress);
        pb.setProgress(newProgress);
    }
};

int[] maxs = {4, 10, 60, 110};
for (int i = 0; i < maxs.length; i++) {
    SeekBar sb = new SeekBar(this);
    sb.setMax(maxs[i]);
    sb.setOnSeekBarChangeListener(l);
    sb.setPadding(20, 20, 20, 0);
    ll.addView(sb);
}

setContentView(ll);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接