手记

炫酷进度条:Android 仿应用宝下载进度条

一、介绍

  1. 一个横向进度条

  2. 下载完成区域有一个滑块不断从左往右滑动(最开始就是被这个吸引的,就想着这个怎么实现的)

  3. 进度条中间显示当前进度,值得注意的是,进度条文本包含在下载区域中的部分显示为白色

  4. 点击暂停,进度条颜色改变,进度文本改变

二、分析

根据以上简单介绍,可以抓住要实现的重难点是上面的第2、3点。

 1. 进度条文本包含在下载区域中的部分显示为白色怎么实现?

这个和歌词变色的效果是一样的,所以实现原理应该差不多。canvas有一个save的方法,然后设置成CLIP_SAVE_FLAG标志,这个标志的解释是restore the current clip when restore() is called.然后结合canvas的clip方法和restore方法就能实现。后文见代码④。

   2.  下载完成区域有一个滑块不断从左往右滑动怎么实现?

首先想到的是画这样一个滑块(其实是一张图片),然后不断根据当前进度修改位置实现移动。需要注意的是这个滑块的移动特点: 滑块的右边界开始进入,最后左边界消失,而且只在下载完成这个区域内有显示(右边界超出下载完成右边界部分不显示)这让我想到两个图层重叠时的显示模式,再看看这幅图,那么这里就可以使用SRC_ATOP模式。

三、实现

1.自定义属性

<declare-styleable name="FlikerProgressBar">
    <attr name="textSize" format="dimension|reference"/>

    <attr name="loadingColor" format="color|reference"/>

    <attr name="stopColor" format="color|reference"/>

</declare-styleable>
private void initAttrs(AttributeSet attrs) {    if (attrs != null) {
        TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.FlikerProgressBar);
        textSize = (int) ta.getDimension(R.styleable.FlikerProgressBar_textSize, dp2px(12));
        loadingColor = ta.getColor(R.styleable.FlikerProgressBar_loadingColor, Color.parseColor("#40c4ff"));
        stopColor = ta.getColor(R.styleable.FlikerProgressBar_stopColor, Color.parseColor("#ff9800"));
        ta.recycle();
    }
}

2.重写onMeasure方法,当height设置为wrap_content时设置为默认高度

@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    super.onMeasure(widthMeasureSpec, heightMeasureSpec);    int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);    int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);    int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);    int height = 0;    switch (heightSpecMode){        case MeasureSpec.AT_MOST:
            height = (int) dp2px(DEFAULT_HEIGHT_DP);            break;        case MeasureSpec.EXACTLY:        case MeasureSpec.UNSPECIFIED:
            height = heightSpecSize;            break;
    }
    setMeasuredDimension(widthSpecSize, height);
}

3.重写onDraw方法

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    //1.边框
    drawBorder(canvas);    //2.进度
    drawProgress();

    canvas.drawBitmap(pgBitmap, 0, 0, null);    //3.进度text
    drawProgressText(canvas);    //4.变色处理
    drawColorProgressText(canvas);
}

①绘制边框

private void drawBorder(Canvas canvas) {
    bgPaint.setStyle(Paint.Style.STROKE);
    bgPaint.setColor(progressColor);
    bgPaint.setStrokeWidth(dp2px(1));
    canvas.drawRect(0, 0, getWidth(), getHeight(), bgPaint);
}

②绘制进度

private void drawProgress() {
    bgPaint.setStyle(Paint.Style.FILL);
    bgPaint.setStrokeWidth(0);
    bgPaint.setColor(progressColor);    float right = (progress / MAX_PROGRESS) * getMeasuredWidth();
    pgBitmap = Bitmap.createBitmap((int) Math.max(right, 1), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
    pgCanvas = new Canvas(pgBitmap);
    pgCanvas.drawColor(progressColor);    if(!isStop){
        bgPaint.setXfermode(xfermode);
        pgCanvas.drawBitmap(flikerBitmap, flickerLeft, 0, bgPaint);
        bgPaint.setXfermode(null);
    }
}

③绘制进度条显示文本

private void drawProgressText(Canvas canvas) {
    textPaint.setColor(progressColor);
    progressText = getProgressText();
    textPaint.getTextBounds(progressText, 0, progressText.length(), textBouds);    int tWidth = textBouds.width();    int tHeight = textBouds.height();    float xCoordinate = (getMeasuredWidth() - tWidth) / 2;    float yCoordinate = (getMeasuredHeight() + tHeight) / 2;
    canvas.drawText(progressText, xCoordinate, yCoordinate, textPaint);
}

④进度条文本变色处理

private void drawColorProgressText(Canvas canvas) {
    textPaint.setColor(Color.WHITE);    int tWidth = textBouds.width();    int tHeight = textBouds.height();    float xCoordinate = (getMeasuredWidth() - tWidth) / 2;    float yCoordinate = (getMeasuredHeight() + tHeight) / 2;    float progressWidth = (progress / MAX_PROGRESS) * getMeasuredWidth();    if(progressWidth > xCoordinate){
        canvas.save(Canvas.CLIP_SAVE_FLAG);        float right = Math.min(progressWidth, xCoordinate + tWidth);
        canvas.clipRect(xCoordinate, 0, right, getMeasuredHeight());
        canvas.drawText(progressText, xCoordinate, yCoordinate, textPaint);
        canvas.restore();
    }
}

四、下载

http://www.apkbus.com/thread-589354-1-1.html

原文链接:http://www.apkbus.com/blog-847095-76694.html

0人推荐
随时随地看视频
慕课网APP