水平渐变进度条的实现

最近在研究一些自定义绘制控件,不可避免的会用到Paint,gradient,
先贴代码:

public class ProgressView1 extends View {

private Paint mOutPaint;
private Paint mInPaint;
private Paint mRecPaint;
private Paint mNumPaint;
private Paint mBgPaint;

private RectF mCurRectF;
private RectF mOutRectF;

private int mWidth;
private int mHeight;

private int mRecRadio;

private int circleRadio;

private int mPadding;



/**
 * 进度条最大值
 */
private float maxCount;
/**
 * 进度条当前值
 */
private float currentCount;


private String mMaxStr;
private String mCurStr;

private int mMaxRadiums;

private static final int[] SECTION_COLORS = {0xFF19DE8E, 0xFF19DE8E, 0xFF21CAE0};
private float mCurSize;

public ProgressView1(Context context) {
    this(context, null);
}

public ProgressView1(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public ProgressView1(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);

    init();
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    mWidth = getMeasuredWidth();
    mHeight = getMeasuredHeight();

    mPadding = mHeight / 6;//padding值
    mRecRadio = mHeight / 2 - mPadding;//进度条宽度
    mMaxRadiums = mHeight / 2;//圆的高度

}

private void init() {

    //外圆
    mOutPaint = new Paint();
    mOutPaint.setStyle(Paint.Style.STROKE);
    // 消除锯齿
    mOutPaint.setAntiAlias(true);
    // 设置画笔的颜色
    mOutPaint.setColor(SECTION_COLORS[0]);
    // 设置paint的外框宽度
    mOutPaint.setStrokeWidth(UIUtils.dp2px(5));

    // 白色实体圆
    mInPaint = new Paint();
    // 消除锯齿
    mInPaint.setAntiAlias(true);
    // 设置画笔的颜色
    mInPaint.setColor(Color.WHITE);


    //进度条画笔
    mRecPaint = new Paint();
    // 消除锯齿
    mRecPaint.setAntiAlias(true);
    // 设置画笔的颜色
    mRecPaint.setColor(SECTION_COLORS[0]);


    //数字画笔
    mNumPaint = new Paint();
    // 消除锯齿
    mNumPaint.setAntiAlias(true);
    // 设置画笔的颜色
    mNumPaint.setColor(SECTION_COLORS[0]);

    mNumPaint.setTextSize(UIUtils.dp2px(14));

    //
    mBgPaint = new Paint();
    // 消除锯齿
    mBgPaint.setAntiAlias(true);


}

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

    mCurStr = String.valueOf((int) currentCount);
    mCurSize = mNumPaint.measureText(mCurStr);

    if (currentCount != maxCount) {
        drawMaxView(canvas);
    }
    drawCurruntView(canvas);
}

private void drawCurruntView(Canvas canvas) {
    float section = currentCount / maxCount;

    if (section <= 1.0f / 3.0f) {
        if (section != 0.0f) {
            mRecPaint.setColor(SECTION_COLORS[0]);
            mOutPaint.setColor(SECTION_COLORS[0]);
        } else {
            mRecPaint.setColor(Color.TRANSPARENT);
            mOutPaint.setColor(Color.TRANSPARENT);
        }
    } else {
        int count = (section <= 1.0f / 3.0f * 2) ? 2 : 3;
        int[] colors = new int[count];
        System.arraycopy(SECTION_COLORS, 0, colors, 0, count);
        float[] positions = new float[count];//这个position数值只创建不使用,是无效的
        if (count == 2) {
            positions[0] = 0.0f;

// positions[1] = 1.0f - positions[0];
positions[1] = 1.0f;
} else {
positions[0] = 0.0f;
positions[1] = (maxCount / 3) / currentCount;
// positions[2] = 1.0f - positions[0] * 2;
positions[2] = 1.0f;
}
positions[positions.length - 1] = 1.0f;//这一句跟上面两句是
LinearGradient shader = new LinearGradient(3, 3, (mWidth - 3) * section, /mHeight - /3,
colors, null, Shader.TileMode.MIRROR);
mRecPaint.setShader(shader);
mOutPaint.setShader(shader);
}

    if (section == 0) {
        //绘制进度条中的空心圆
        mOutPaint.setColor(SECTION_COLORS[0]);
        canvas.drawCircle(mPadding + mRecRadio, mHeight / 2,
                mMaxRadiums - mOutPaint.getStrokeWidth() / 2, mOutPaint);
        mInPaint.setColor(Color.WHITE);

// //画实体圆
canvas.drawCircle(mPadding + mRecRadio, mHeight / 2,
mRecRadio, mInPaint);
//
// //画当前的文字
mNumPaint.setColor(SECTION_COLORS[0]);
canvas.drawText(mCurStr, mPadding + mRecRadio - mCurSize / 2
, mHeight / 2 + mCurSize / 2, mNumPaint);//绘制文字这里确定绘制文字的坐下角坐标
} else {
mCurRectF = new RectF(mPadding, mPadding, mWidth * section - mPadding, mHeight - mPadding);//正确的右边距是(mWidth-2*padding)*selection+padding,但实际上这细小的差距是无法肉眼识别的
canvas.drawRoundRect(mCurRectF, mRecRadio, mRecRadio, mRecPaint);

// canvas.drawCircle(mWidth * section - mPadding - mRecRadio, mHeight / 2,
// mMaxRadiums - mOutPaint.getStrokeWidth() / 2, mOutPaint);
//绘制外圈
canvas.drawCircle(mPadding + (mWidth - 2 * mPadding) * section - mRecRadio, mHeight / 2, mMaxRadiums - mOutPaint.getStrokeWidth() / 2, mOutPaint);

        mInPaint.setColor(Color.WHITE);

//
// //画实体圆
// canvas.drawCircle(mWidth * section - mPadding - mRecRadio, mHeight / 2,
// mRecRadio, mInPaint);
canvas.drawCircle(mPadding + (mWidth - 2 * mPadding) * section - mRecRadio, mHeight / 2,
mRecRadio, mInPaint);
//
// //画当前的文字
mNumPaint.setColor(SECTION_COLORS[0]);
canvas.drawText(mCurStr, mWidth * section - mRecRadio - mPadding - mCurSize / 2
, mHeight / 2 + mCurSize / 2, mNumPaint);
}

// }

}

private void drawMaxView(Canvas canvas) {
    //绘制圆角矩形
    mBgPaint.setColor(0xFFDDE0E4);
    mOutRectF = new RectF(mPadding, mPadding, mWidth - mPadding, mHeight - mPadding);
    canvas.drawRoundRect(mOutRectF, mRecRadio, mRecRadio, mBgPaint);

    //绘制末尾的圆形
    mInPaint.setColor(0xFFDDE0E4);
    canvas.drawCircle(mWidth - mPadding - mMaxRadiums, mHeight / 2, mMaxRadiums, mInPaint);

    //绘制进度末尾的总进度数值
    mNumPaint.setColor(0xFF9AA3B3);
    Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD);
    mNumPaint.setTypeface(font);
    mMaxStr = String.valueOf((int) maxCount);
    canvas.drawText(mMaxStr, mWidth - mMaxRadiums - mPadding - mCurSize / 2, mHeight / 2 +
            mCurSize / 2, mNumPaint);

}


public void setMaxCount(float maxCount) {
    this.maxCount = maxCount;
}

/***
 * 设置当前的进度值
 *
 * @param currentCount
 */
public void setCurrentCount(float currentCount) {
    this.currentCount = currentCount > maxCount ? maxCount : currentCount;
    invalidate();
}

}

1.首先,在控件的onMeasure方法中
mWidth = getMeasuredWidth();
mHeight = getMeasuredHeight();
获取到控件的宽高然后根据宽高设置控件的padding圆的半径等等,简而言之就是,初始化控件的尺寸信息

2.第二步,drawMaxView()方法绘进度条总得长度

3.第三步,drawCurruntView()方法,绘制当前进度,这里用到了
LinearGradient shader = new LinearGradient(3, 3, (mWidth - 3) * section, /mHeight - /3,
colors, null, Shader.TileMode.MIRROR);
渐变渲染的一个对象,设置了这个对象开始渲染和结束渲染的位置,通过这个对象达到进度条颜色渐变的效果

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值