如何在可绘制图层列表的一侧使用图像

How can I use an image on the side of a drawable layer list

我的 UI 设计师想出了这样的进度条设计:

数字应该是进度和最大值。

圆形图像将会改变。在某些设计上,1500 旁边还有一张图片。

每当我尝试在 layer-list 上执行此操作时,我总是以可绘制对象中间的图像结束。理想情况下,我更喜欢使用矢量图形,但如果需要我可以使用 png。我什至还没有考虑将数字放在那里。

那么如何实现呢?

谢谢。

在我看来,使用 canvas 对于这种情况似乎更容易。这是我现在可以想出的一个简短示例:

public class Loading extends View {

private final static float VIEW_HEIGHT = 80;
private RectF viewRectangle;
private RectF progressRectangle;
private float cornersRadius;

private Paint progressBarPaint;
private Paint progressTextPaint;
private Paint containerBarPaint;
private Paint containerTextPaint;

private final int progressMaxValue = 1500;
private float containerTextY;
private float containerTextX;

private final float whiteCircleRadius = 14;
private final float progressTextPadding = 16;

private float progress;

public Loading(Context context) {
    super(context);
    progress = 0.5f;
    progressTextPaint = new Paint(LINEAR_TEXT_FLAG|SUBPIXEL_TEXT_FLAG|ANTI_ALIAS_FLAG);
    progressTextPaint.setColor(Color.WHITE);
    progressTextPaint.setStyle(Paint.Style.FILL_AND_STROKE);
    progressTextPaint.setTextSize(28);
    progressTextPaint.setStrokeWidth(1f);

    containerTextPaint = new Paint(progressTextPaint);
    containerTextPaint.setColor(Color.BLACK);
    progressBarPaint = new Paint(ANTI_ALIAS_FLAG);
    progressBarPaint.setColor(Color.BLUE);
    progressBarPaint.setStyle(Paint.Style.FILL);
    containerBarPaint = new Paint(ANTI_ALIAS_FLAG);
    containerBarPaint.setColor(Color.GRAY);
    containerBarPaint.setStyle(Paint.Style.FILL);
}

@Override
protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
    int horizontalPadding = getPaddingLeft() + getPaddingRight();
    int verticalPadding = getPaddingTop() + getPaddingBottom();
    float measuredHeight = height - verticalPadding;
    float targetHeight = measuredHeight < VIEW_HEIGHT ? measuredHeight : VIEW_HEIGHT;
    float containerWidth = width - horizontalPadding;

    viewRectangle = new RectF(getPaddingLeft(), getPaddingTop(), containerWidth, targetHeight);
    progressRectangle = new RectF(viewRectangle);
    cornersRadius = targetHeight / 2;

    String maxValueText = String.valueOf(progressMaxValue);
    Rect containerTextBounds = new Rect();
    containerTextPaint.getTextBounds(maxValueText, 0, maxValueText.length(), containerTextBounds);
    containerTextX = viewRectangle.right - containerTextBounds.width() - cornersRadius / 2;
    containerTextY = viewRectangle.centerY() - containerTextBounds.exactCenterY();
}

@Override
protected void onDraw(Canvas canvas) {
    float progressWidth = viewRectangle.right * progress;
    float cornerDiameter = cornersRadius * 2;
    progressRectangle.right = progressWidth > cornerDiameter ? progressWidth : cornerDiameter;
    canvas.drawRoundRect(viewRectangle, cornersRadius, cornersRadius, containerBarPaint);
    canvas.drawRoundRect(progressRectangle, cornersRadius, cornersRadius, progressBarPaint);
    canvas.drawCircle(progressRectangle.right - cornersRadius, progressRectangle.centerY(), whiteCircleRadius, progressTextPaint);
    canvas.drawText(String.valueOf(progressMaxValue), containerTextX, containerTextY, containerTextPaint);

    String progressText = String.valueOf((int) (progressMaxValue * progress));
    float progressTextWidth = progressTextPaint.measureText(progressText);

    if (progressTextWidth < progressRectangle.right * 2) {
        float requiredProgressTextSpace = cornersRadius + whiteCircleRadius + progressTextPadding + progressTextWidth;
        canvas.drawText(progressText, progressRectangle.right - requiredProgressTextSpace, containerTextY, progressTextPaint);
    }
}

}

它远非完美,也不是很灵活,但这是一个很好的起点。如果您在这里需要一些评论,请随时提出。这是上面代码的渲染: