如何使线条曲线形状填充图像

时间:2014-07-03 06:53:50

标签: android progress-bar

enter image description here

我使用来自Github android square progress bar的方形进度条库,一切正常但我想让条形图填满我的图像..任何人都有这个想法。???

import java.text.DecimalFormat;

import net.yscs.android.square_progressbar.utils.CalculationUtil;
import net.yscs.android.square_progressbar.utils.PercentStyle;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;

public class SquareProgressView extends View {

    private double progress;
    private final Paint progressBarPaint;
    private final Paint outlinePaint;
    private final Paint textPaint;

    private float widthInDp = 10;
    private float strokewidth = 0;
    private Canvas canvas;

    private boolean outline = false;
    private boolean startline = false;
    private boolean showProgress = false;

    private PercentStyle percentSettings = new PercentStyle(Align.CENTER, 150,
            true);
    private boolean clearOnHundred = false;

    public SquareProgressView(Context context) {
        super(context);
        progressBarPaint = new Paint();
        progressBarPaint.setColor(context.getResources().getColor(
                android.R.color.holo_green_dark));
        progressBarPaint.setStrokeWidth(CalculationUtil.convertDpToPx(
                widthInDp, getContext()));
        progressBarPaint.setAntiAlias(true);
        progressBarPaint.setStyle(Style.STROKE);

        outlinePaint = new Paint();
        outlinePaint.setColor(context.getResources().getColor(
                android.R.color.black));
        outlinePaint.setStrokeWidth(1);
        outlinePaint.setAntiAlias(true);
        outlinePaint.setStyle(Style.STROKE);

        textPaint = new Paint();
        textPaint.setColor(context.getResources().getColor(
                android.R.color.black));
        textPaint.setAntiAlias(true);
        textPaint.setStyle(Style.STROKE);

    }

    public SquareProgressView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        progressBarPaint = new Paint();
        progressBarPaint.setColor(context.getResources().getColor(
                android.R.color.holo_green_dark));
        progressBarPaint.setStrokeWidth(CalculationUtil.convertDpToPx(
                widthInDp, getContext()));
        progressBarPaint.setAntiAlias(true);
        progressBarPaint.setStyle(Style.STROKE);

        outlinePaint = new Paint();
        outlinePaint.setColor(context.getResources().getColor(
                android.R.color.black));
        outlinePaint.setStrokeWidth(1);
        outlinePaint.setAntiAlias(true);
        outlinePaint.setStyle(Style.STROKE);

        textPaint = new Paint();
        textPaint.setColor(context.getResources().getColor(
                android.R.color.black));
        textPaint.setAntiAlias(true);
        textPaint.setStyle(Style.STROKE);
    }

    public SquareProgressView(Context context, AttributeSet attrs) {
        super(context, attrs);
        progressBarPaint = new Paint();
        progressBarPaint.setColor(context.getResources().getColor(
                android.R.color.holo_green_dark));
        progressBarPaint.setStrokeWidth(CalculationUtil.convertDpToPx(
                widthInDp, getContext()));
        progressBarPaint.setAntiAlias(true);
        progressBarPaint.setStyle(Style.STROKE);

        outlinePaint = new Paint();
        outlinePaint.setColor(context.getResources().getColor(
                android.R.color.black));
        outlinePaint.setStrokeWidth(1);
        outlinePaint.setAntiAlias(true);
        outlinePaint.setStyle(Style.STROKE);

        textPaint = new Paint();
        textPaint.setColor(context.getResources().getColor(
                android.R.color.black));
        textPaint.setAntiAlias(true);
        textPaint.setStyle(Style.STROKE);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        this.canvas = canvas;
        super.onDraw(canvas);
        strokewidth = CalculationUtil.convertDpToPx(widthInDp, getContext());
        float scope = canvas.getWidth() + canvas.getHeight()
                + canvas.getHeight() + canvas.getWidth();
        float percent = (scope / 100) * Float.valueOf(String.valueOf(progress));
        float halfOfTheImage = canvas.getWidth() / 2;

        if (outline) {
            drawOutline();
        }

        if (isStartline()) {
            drawStartline();
        }

        if (showProgress) {
            drawPercent(percentSettings);
        }

        if (clearOnHundred && progress == 100.0) {
            return;
        }

        Path path = new Path();
        if (percent > halfOfTheImage) {
            paintFirstHalfOfTheTop(canvas);
            float second = percent - halfOfTheImage;

            if (second > canvas.getHeight()) {
                paintRightSide(canvas);
                float third = second - canvas.getHeight();

                if (third > canvas.getWidth()) {
                    paintBottomSide(canvas);
                    float forth = third - canvas.getWidth();

                    if (forth > canvas.getHeight()) {
                        paintLeftSide(canvas);
                        float fifth = forth - canvas.getHeight();

                        if (fifth == halfOfTheImage) {
                            paintSecondHalfOfTheTop(canvas);
                        } else {
                            path.moveTo(strokewidth, (strokewidth / 2));
                            path.lineTo(strokewidth + fifth, (strokewidth / 2));
                            canvas.drawPath(path, progressBarPaint);
                        }
                    } else {
                        path.moveTo((strokewidth / 2), canvas.getHeight()
                                - strokewidth);
                        path.lineTo((strokewidth / 2), canvas.getHeight()
                                - forth);
                        canvas.drawPath(path, progressBarPaint);
                    }

                } else {
                    path.moveTo(canvas.getWidth() - strokewidth,
                            canvas.getHeight() - (strokewidth / 2));
                    path.lineTo(canvas.getWidth() - third, canvas.getHeight()
                            - (strokewidth / 2));
                    canvas.drawPath(path, progressBarPaint);
                }
            } else {
                path.moveTo(canvas.getWidth() - (strokewidth / 2), strokewidth);
                path.lineTo(canvas.getWidth() - (strokewidth / 2), strokewidth
                        + second);
                canvas.drawPath(path, progressBarPaint);
            }

        } else {
            path.moveTo(halfOfTheImage, strokewidth / 2);
            path.lineTo(halfOfTheImage + percent, strokewidth / 2);
            canvas.drawPath(path, progressBarPaint);
        }

    }

    private void drawStartline() {
        Path outlinePath = new Path();
        outlinePath.moveTo(canvas.getWidth() / 2, 0);
        outlinePath.lineTo(canvas.getWidth() / 2, strokewidth);
        canvas.drawPath(outlinePath, outlinePaint);
    }

    private void drawOutline() {
        Path outlinePath = new Path();
        outlinePath.moveTo(0, 0);
        outlinePath.lineTo(canvas.getWidth(), 0);
        outlinePath.lineTo(canvas.getWidth(), canvas.getHeight());
        outlinePath.lineTo(0, canvas.getHeight());
        outlinePath.lineTo(0, 0);
        canvas.drawPath(outlinePath, outlinePaint);
    }

    public void paintFirstHalfOfTheTop(Canvas canvas) {
        Path path = new Path();
        path.moveTo(canvas.getWidth() / 2, strokewidth / 2);
        path.lineTo(canvas.getWidth() + strokewidth, strokewidth / 2);
        canvas.drawPath(path, progressBarPaint);
    }

    public void paintRightSide(Canvas canvas) {
        Path path = new Path();
        path.moveTo(canvas.getWidth() - (strokewidth / 2), strokewidth);
        path.lineTo(canvas.getWidth() - (strokewidth / 2), canvas.getHeight());
        canvas.drawPath(path, progressBarPaint);
    }

    public void paintBottomSide(Canvas canvas) {
        Path path = new Path();
        path.moveTo(canvas.getWidth() - strokewidth, canvas.getHeight()
                - (strokewidth / 2));
        path.lineTo(0, canvas.getHeight() - (strokewidth / 2));
        canvas.drawPath(path, progressBarPaint);
    }

    public void paintLeftSide(Canvas canvas) {
        Path path = new Path();
        path.moveTo((strokewidth / 2), canvas.getHeight() - strokewidth);
        path.lineTo((strokewidth / 2), 0);
        canvas.drawPath(path, progressBarPaint);
    }

    public void paintSecondHalfOfTheTop(Canvas canvas) {
        Path path = new Path();
        path.moveTo(strokewidth, (strokewidth / 2));
        path.lineTo(canvas.getWidth() / 2, (strokewidth / 2));
        canvas.drawPath(path, progressBarPaint);
    }

    public double getProgress() {
        return progress;
    }

    public void setProgress(double progress) {
        this.progress = progress;
        this.invalidate();
    }

    public void setColor(int color) {
        progressBarPaint.setColor(color);
        this.invalidate();
    }

    /**
     * @return the border
     */
    public float getWidthInDp() {
        return widthInDp;
    }

    /**
     * @return the border
     */
    public void setWidthInDp(int width) {
        this.widthInDp = width;
        progressBarPaint.setStrokeWidth(CalculationUtil.convertDpToPx(
                widthInDp, getContext()));
        this.invalidate();
    }

    public boolean isOutline() {
        return outline;
    }

    public void setOutline(boolean outline) {
        this.outline = outline;
        this.invalidate();
    }

    public boolean isStartline() {
        return startline;
    }

    public void setStartline(boolean startline) {
        this.startline = startline;
        this.invalidate();
    }

    private void drawPercent(PercentStyle setting) {
        textPaint.setTextAlign(setting.getAlign());
        if (setting.getTextSize() == 0) {
            textPaint.setTextSize((canvas.getHeight() / 10) * 4);
        } else {
            textPaint.setTextSize(setting.getTextSize());
        }

        String percentString = new DecimalFormat("###").format(getProgress());
        if (setting.isPercentSign()) {
            percentString = percentString + percentSettings.getCustomText();
        }

        textPaint.setColor(percentSettings.getTextColor());

        canvas.drawText(
                percentString,
                canvas.getWidth() / 2,
                (int) ((canvas.getHeight() / 2) - ((textPaint.descent() + textPaint
                        .ascent()) / 2)), textPaint);
    }

    public boolean isShowProgress() {
        return showProgress;
    }

    public void setShowProgress(boolean showProgress) {
        this.showProgress = showProgress;
        this.invalidate();
    }

    public void setPercentStyle(PercentStyle percentSettings) {
        this.percentSettings = percentSettings;
        this.invalidate();
    }

    public PercentStyle getPercentStyle() {
        return percentSettings;
    }

    public void setClearOnHundred(boolean clearOnHundred) {
        this.clearOnHundred = clearOnHundred;
        this.invalidate();
    }

    public boolean isClearOnHundred() {
        return clearOnHundred;
    }

}

上面的代码用于创建方形进度条。 提前致谢。

1 个答案:

答案 0 :(得分:2)

我想在几周前将这种可能性添加到图书馆。但问题是,我正在使用Path来计算图像周围的进度。当你只绘制部分路径和弧时(进度),似乎很难处理路径和弧。但我做了一些研究,发现了这两种方法,一般可以绘制圆角:

Canvas - drawRoundRect

drawRoundRect)是Canvas提供的方法。但这里的问题是你需要给方法一个矩形,然后圆角。正如我上面所说,我正在使用一条路径来绘制进度。所以据我所见,你不能将它用于我的库代码,以增加圆角的可能性。

路径 - addArc / arcTo

路径本身有两种方法(addArc / arcTo)来处理弧。但问题是,如果你使用它们在路径上应用一些圆角,那么你就有了显示正确百分比的问题。因为你需要一种不同的方法来计算弧线的走向。所以这是一种可能性,但它需要重写/扩展我当前的进度计算。

也许有另一种解决方案,我没想过。但目前在图书馆中没有任何支持方式可以解决这个问题。但是你可以用上面的两个弧形方法来尝试它。如果您希望我(或其他人)尝试将其添加到库中,请添加新的issue to the github repository