在自定义视图中显示曲线形状进度

时间:2015-05-25 06:57:28

标签: android progress-bar custom-view

我正在处理圆形的自定义视图。几乎我已经完成了创建自定义类并实现它。但我的问题是在不同颜色的曲线形状中显示出不同的进展,这取决于动态数据。这是我实施的图像enter image description here

我想要这样http://imgur.com/cmNKWBF

所以我的问题是如何用不同的颜色和动态数据绘制弧形(曲线形状)进度。

帮助将不胜感激!!

2 个答案:

答案 0 :(得分:2)

最后,我在Custom CircleView类中进行了一些更改后解决了这个问题。为此,我为每个地区计算了sweepAnglestartAngle。这是我发布的代码的一部分。

我必须显示三个不同的区域,所以我为每个区域采用了三个不同的Paints和声明变量。像,

private float   absStart;
private float   absSweep;
private float   preStart;
private float   preSweep;
private float   vacStart;
private float   vacSweep;

private Paint   absPaint;
private Paint   prePaint;
private Paint   vacPaint;

现在初始化你的所有三个地区的油漆。在这里,我只发布其中一个

absPaint = new Paint();
absPaint.setStrokeCap(Paint.Cap.ROUND);
absPaint.setStyle(Paint.Style.STROKE);
absPaint.setStrokeJoin(Paint.Join.ROUND);
absPaint.setColor(Color.parseColor("#eb537a"));
absPaint.setStrokeWidth((float) 22.5);

现在计算每个区域的区域我创建了一个名为updateAngles()的方法,它有三个浮点参数

public void updateAngles(float absPercent, float prePercent, float vacPercent) {
    float total = absPercent + prePercent + vacPercent;
    absStart = 0;
    absSweep = (absPercent / total) * 360;
    preStart = absSweep;
    preSweep = (prePercent / total) * 360;
    vacStart = absSweep + preSweep;
    vacSweep = (vacPercent / total) * 360;

    Log.e("Angles are:", absStart + ":" + absSweep + ":" + preStart + ":" + preSweep + ":" + vacStart + ":" + vacSweep);
    invalidate();
}

此方法将在初始化CircleView后调用您所需的活动,并调用cv.updateAngles(20,20,60);,其中cvCircleView的对象。

现在在onDraw()方法中,您需要为每个区域绘制弧。

 mInnerRectF.set(45, 45, 330, 330);
 canvas.drawArc(mInnerRectF, absStart, absSweep, false, absPaint);
 canvas.drawArc(mInnerRectF, preStart, preSweep, false, prePaint);
 canvas.drawArc(mInnerRectF, vacStart, vacSweep, false, vacPaint);

所以这最终给了我一个我想要的输出。

但是,如果依赖于不同的设备,如移动屏幕,7英寸和10英寸平板电脑,那么您应该使用DisplayMetrics

答案 1 :(得分:1)

以下代码符合您的要求。

public class ProgressWidget extends View {

    private int percent = 25;
    private int radiusOuter = 110, radiusInner = 90;
    private Paint mPaintOuter;
    private Paint mPaintPercent;
    private Paint mInnerCircle, mTextPaint;
    private int mCenterX, mCenterY;
    private int textSize;
    private String mTimedText = percent+"%";
    private int desiredWidth = 300;
    private int desiredHeight = 300;
    private boolean isRunning;
    private boolean isMeasured;

    public ProgressWidget(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initialization();
    }

    public ProgressWidget(Context context, AttributeSet attrs) {
        super(context, attrs);
        initialization();
    }

    public ProgressWidget(Context context) {
        super(context);
        initialization();
    }

    private void initialization() {

        mPaintOuter = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaintOuter.setColor(Color.DKGRAY);

        mPaintPercent = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaintPercent.setColor(Color.CYAN);

        mInnerCircle = new Paint(Paint.ANTI_ALIAS_FLAG);
        mInnerCircle.setColor(Color.BLACK);

        mTextPaint = new Paint();
        mTextPaint.setColor(Color.CYAN);
        mTextPaint.setTextSize(textSize);
    }

    public void getUpdateRadius() {
        if (!isMeasured) {
            isMeasured = true;
            int size = getWidgetWidth() < getWidgetHeight() ? getWidgetWidth() : getWidgetHeight();

            radiusOuter = (int) (size * 0.35f);
            radiusInner = (int) (size * 0.3f);

            textSize = (int) (size * 0.08f);
            setTimedTextSize(textSize);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        mCenterX = getWidth() / 2;
        mCenterY = getHeight() / 2;

        drawSecCircle(canvas);
        drawInnerCircle(canvas);
        drawPercentageText(canvas);
    }

    private void drawInnerCircle(Canvas canvas) {
        canvas.drawCircle(mCenterX, mCenterY, radiusInner, mInnerCircle);
    }

    private void drawSecCircle(Canvas canvas) {

        canvas.drawCircle(mCenterX, mCenterY, radiusOuter, mPaintOuter);
        canvas.drawArc(new RectF(mCenterX - radiusOuter, mCenterY - radiusOuter, mCenterX + radiusOuter, mCenterY + radiusOuter), -90, percent*3.6f, true, mPaintPercent);
    }

    public void drawPercentageText(Canvas canvas) {
        RectF areaRect = new RectF(mCenterX - radiusInner, mCenterY - radiusInner, mCenterX + radiusInner, mCenterY + radiusInner);
        RectF bounds = new RectF(areaRect);

        // measure text width
        bounds.right = mTextPaint.measureText(mTimedText, 0, mTimedText.length());
        // measure text height
        bounds.bottom = mTextPaint.descent() - mTextPaint.ascent();

        bounds.left += (areaRect.width() - bounds.right) / 2.0f;
        bounds.top += (areaRect.height() - bounds.bottom) / 2.0f;

        canvas.drawText(mTimedText, bounds.left, bounds.top - mTextPaint.ascent(), mTextPaint);
    }

    public void setTimedTextSize(int textSize) {
        this.textSize = textSize;
        mTextPaint.setTextSize(textSize);
    }

    public void setTimedText(String timedText) {
        this.mTimedText = timedText;
        invalidate();
    }

    public void setPercentage(int percent) {
        this.percent = percent;

        mTimedText = String.valueOf(percent)+"%";
        invalidate();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        setWidgetWidth((int) (widthSize * 0.6));
        setWidgetHeight((int) (heightSize * 0.6));

        int width;
        int height;

        //Measure Width
        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthSize;
        } else if (widthMode == MeasureSpec.AT_MOST) {
            width = Math.min(getWidgetWidth(), widthSize);
        } else {
            width = getWidgetWidth();
        }

        if (heightMode == MeasureSpec.EXACTLY) {
            height = heightSize;
        } else if (heightMode == MeasureSpec.AT_MOST) {
            height = Math.min(getWidgetHeight(), heightSize);
        } else {
            height = getWidgetHeight();
        }

        setWidgetWidth(width);
        setWidgetHeight(height);

        getUpdateRadius();

        setMeasuredDimension(width, height);
    }


    public int getWidgetWidth() {
        return desiredWidth;
    }

    public void setWidgetWidth(int clockWidgetWidth) {

        this.desiredWidth = clockWidgetWidth;
    }

    public int getWidgetHeight() {
        return desiredHeight;
    }

    public void setWidgetHeight(int clockWidgetHeight) {
        this.desiredHeight = clockWidgetHeight;
    }
}