最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android實(shí)現(xiàn)下載進(jìn)度條效果

 更新時(shí)間:2021年06月16日 14:47:42   作者:h2coder  
vivo商店在下載應(yīng)用的時(shí)候,底部有一個(gè)圓角矩形的下載進(jìn)度條,中間有一個(gè)進(jìn)度文字,而且進(jìn)度和文字交匯的時(shí)候,交匯部分的文字會(huì)從藍(lán)色邊為白色,會(huì)有一種一半白色字,一半藍(lán)色字的效果。本文將仿照該樣式實(shí)現(xiàn)一個(gè)

最終效果和對(duì)比vivo商店效果

vivo應(yīng)用商店下載效果:

最終實(shí)現(xiàn)效果:

分析1 - 計(jì)算進(jìn)度

進(jìn)度計(jì)算就比較簡(jiǎn)單了,我們通過復(fù)寫onSizeChanged()方法,獲取到控件的寬后,先計(jì)算當(dāng)前進(jìn)度百分比,再將百分比乘以寬度,就可以得到應(yīng)該繪制的寬度了。

繪制圓角矩形需要傳一個(gè)Rect,Rect的構(gòu)造方法需要傳4個(gè)位置,分別是left、top、right、bottom,我們主要是計(jì)算不斷變化的right值。在drawProgress()方法中,right值為最大的寬度 * 進(jìn)度百分比值。

/**
 * 控件寬
 */
private int mViewWidth;
/**
 * 控件高
 */
private int mViewHeight;
/**
 * 圓角弧度
 */
private float mRadius;
/**
 * 當(dāng)前進(jìn)度
 */
private int mProgress;
/**
 * 最大進(jìn)度值
 */
private int mMaxProgress;

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //畫進(jìn)度條
    drawProgress(canvas);
}

/**
 * 畫進(jìn)度
 */
private void drawProgress(Canvas canvas) {
    RectF rect = new RectF(getFrameLeft(), getFrameTop(), getFrameRight() * getProgressRatio(), getFrameBottom());
    canvas.drawRect(rect, mProgressPaint);
}

/**
 * 獲取當(dāng)前進(jìn)度值比值
 */
private float getProgressRatio() {
    return (mProgress / (mMaxProgress * 1.0f));
}

//------------ getFrameXxx()方法都是處理padding ------------

private float getFrameLeft() {
    return getPaddingStart();
}

private float getFrameRight() {
    return mViewWidth - getPaddingEnd();
}

private float getFrameTop() {
    return getPaddingTop();
}

private float getFrameBottom() {
    return mViewHeight - getPaddingBottom();
}

//------------ getFrameXxx()方法都是處理padding ------------

分析2 - 繪制圓角矩形

背景和進(jìn)度條,都是圓角矩形,我們可以使用canvas.drawRoundRect()的API來繪制。但是使用canvas.drawRoundRect()會(huì)有個(gè)問題,當(dāng)進(jìn)度比較小的時(shí)候,例如1%,計(jì)算出來的矩形長度比較小,會(huì)導(dǎo)致圓角不是滿的,缺陷效果見動(dòng)圖(注意看剛從左側(cè)出來時(shí)圓角的大?。?。

public class DownloadProgressView extends View {
    ...省略其他代碼

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mViewWidth = w;
        mViewHeight = h;
        //計(jì)算出圓角半徑
        mRadius = Math.min(mViewWidth, mViewHeight) / 2f;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //畫背景
        drawBg(canvas);
        //畫進(jìn)度條
        drawProgress(canvas);
    }

    /**
     * 畫背景
     */
    private void drawBg(Canvas canvas) {
        canvas.drawRoundRect(new RectF(getFrameLeft(), getPaddingTop(), getFrameRight(), getFrameBottom()), mRadius, mRadius, mBgPaint);
    }

    /**
     * 畫進(jìn)度
     */
    private void drawProgress(Canvas canvas) {
        RectF rect = new RectF(getFrameLeft(), getFrameTop(), getFrameRight() * getProgressRatio(), getFrameBottom());
        canvas.drawRoundRect(rect, mRadius, mRadius, mProgressPaint);
    }

    //------------ getFrameXxx()方法都是處理padding ------------

    private float getFrameLeft() {
        return getPaddingStart();
    }

    private float getFrameRight() {
        return mViewWidth - getPaddingEnd();
    }

    private float getFrameTop() {
        return getPaddingTop();
    }

    private float getFrameBottom() {
        return mViewHeight - getPaddingBottom();
    }

    //------------ getFrameXxx()方法都是處理padding ------------
}

解決方案

我的方案是這樣的,不使用drawRoundRect()方法來繪制圓角矩形,而是先使用canvas.clipPath()方法,添加一個(gè)有圓角矩形的Path,來裁切畫布,再drawRect()方法來繪制一個(gè)長矩形,就保持了圓角。

但clipPath()也有一個(gè)缺點(diǎn),就是裁切出來的圓角會(huì)有鋸齒,Paint設(shè)置了setAntiAlias(true)也沒有用,大家有好的方法,互相學(xué)習(xí)一下!

public class DownloadProgressView extends View {
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //裁剪圓角
        clipRound(canvas);
        //畫背景
        drawBg(canvas);
        //畫進(jìn)度條
        drawProgress(canvas);
    }

    /**
     * 裁剪圓角
     */
    private void clipRound(Canvas canvas) {
        Path path = new Path();
        RectF roundRect = new RectF(getFrameLeft(), getFrameTop(), getFrameRight(), getFrameBottom());
        path.addRoundRect(roundRect, mRadius, mRadius, Path.Direction.CW);
        canvas.clipPath(path);
    }

    /**
     * 畫背景
     */
    private void drawBg(Canvas canvas) {
        canvas.drawRect(new RectF(getFrameLeft(), getPaddingTop(), getFrameRight(), getFrameBottom()), mBgPaint);
    }

    /**
     * 畫進(jìn)度
     */
    private void drawProgress(Canvas canvas) {
        RectF rect = new RectF(getFrameLeft(), getFrameTop(), getFrameRight() * getProgressRatio(), getFrameBottom());
        canvas.drawRect(rect, mProgressPaint);
    }
}

分析3 - 繪制文字和交匯

要讓文字和進(jìn)度交匯時(shí),讓藍(lán)色變?yōu)榘咨?,需要使用到PorterDuffXfermode。PorterDuffXfermode可以將2個(gè)圖像進(jìn)行合成,或者簡(jiǎn)單說為相交模式,而合成方式有16種,見下圖。(Src藍(lán)色方塊為上層圖層,Dst黃色圓形為下層圖層。)

查閱文檔,我們發(fā)現(xiàn)SrcATop模式比較符合我們的需求,在SrcATop模式下,Src圖層不覆蓋Dst圖層的像素會(huì)被拋棄,只保留Src圖層覆蓋Dst圖層的圖層像素。

我們的思路是這樣的:畫4個(gè)圖層,最底部的灰色背景圖層,再上一層藍(lán)色進(jìn)度圖層,接著是文字圖層,最上層是一層白色的進(jìn)度圖層,重點(diǎn)在畫文字和白色進(jìn)度圖層是添加了PorterDuffXfermode(SrcATop模式)。

白色進(jìn)度和藍(lán)色進(jìn)度的大小一直是同步的,但是因?yàn)镻orterDuffXfermode的原因,白色圖層未覆蓋到文字時(shí),一直都是被拋棄圖層像素,相當(dāng)于是透明的,只有當(dāng)和文字相交時(shí),才會(huì)繪制出白色圖層,就顯示出了一半白色文字,一半藍(lán)色文字的效果,而其他部分都沒有和文字相交都被拋棄,都為透明。

繪制文字、白色進(jìn)度圖層代碼,見drawText()方法。

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //裁剪圓角
    clipRound(canvas);
    //畫背景
    drawBg(canvas);
    //畫進(jìn)度條
    drawProgress(canvas);
    //畫文字圖層
    drawText(canvas);
}

/**
 * 畫文字
 */
private void drawText(Canvas canvas) {
    mTextPaint.setColor(mPercentageTextColor);
    //創(chuàng)建文字圖層
    Bitmap textBitmap = Bitmap.createBitmap(mViewWidth, mViewHeight, Bitmap.Config.ARGB_8888);
    Canvas textCanvas = new Canvas(textBitmap);
    String textContent = mProgress + "%";
    //計(jì)算文字Y軸坐標(biāo)
    float textY = mViewHeight / 2.0f - (mTextPaint.getFontMetricsInt().descent / 2.0f + mTextPaint.getFontMetricsInt().ascent / 2.0f);
    textCanvas.drawText(textContent, mViewWidth / 2.0f, textY, mTextPaint);
    //畫最上層的白色圖層,未相交時(shí)不會(huì)顯示出來
    mTextPaint.setColor(mPercentageTextColor2);
    mTextPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
    textCanvas.drawRect(new RectF(getFrameLeft(), getFrameTop(), getFrameRight() * getProgressRatio(), getFrameBottom()), mTextPaint);
    //畫結(jié)合后的圖層
    canvas.drawBitmap(textBitmap, getFrameLeft(), getFrameTop(), mTextPaint);
    mTextPaint.setXfermode(null);
    textBitmap.recycle();
}

手勢(shì)拓展

經(jīng)過上面的進(jìn)度、文字、交匯處理,進(jìn)度條算是完整了,接下來拓展一下沒有的東西,例如手勢(shì)拖動(dòng),就像SeekBar一樣,當(dāng)我們觸摸進(jìn)度條時(shí),進(jìn)度會(huì)隨著移動(dòng)而改變進(jìn)度。

我們先重寫dispatchTouchEvent()方法,當(dāng)down事件來到時(shí),讓父控件不攔截,我們進(jìn)行攔截。接著重寫onTouchEvent()方法,計(jì)算Move、Up時(shí),移動(dòng)的距離,計(jì)算出百分比和應(yīng)有的進(jìn)度值,然后不斷調(diào)用setProgress()來更新進(jìn)度。

public class DownloadProgressView extends View {
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        int action = event.getAction();
        //攔截事件,然后讓父類不進(jìn)行攔截
        if (mControlMode == MODE_TOUCH && action == MotionEvent.ACTION_DOWN) {
            getParent().requestDisallowInterceptTouchEvent(true);
            return true;
        }
        return super.dispatchTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //拽托模式下才起效果
        if (mControlMode == MODE_TOUCH) {
            int action = event.getAction();
            //包裹Down事件時(shí)的x坐標(biāo)
            if (action == MotionEvent.ACTION_DOWN) {
                mTouchDownX = event.getX();
                return true;
            } else if (action == MotionEvent.ACTION_MOVE || action == MotionEvent.ACTION_UP) {
                //Move或Up的時(shí)候,計(jì)算拽托進(jìn)度
                float endX = event.getX();
                //計(jì)算公式:百分比值 = 移動(dòng)距離 / 總長度
                float distanceX = Math.abs(endX - mTouchDownX);
                float ratio = (distanceX * 1.0f) / (getFrameRight() - getFrameLeft());
                //計(jì)算百分比應(yīng)該有的進(jìn)度:進(jìn)度 = 總進(jìn)度 * 進(jìn)度百分比值
                float progress = mMaxProgress * ratio;
                setProgress((int) progress);
                return true;
            }
            return super.onTouchEvent(event);
        } else {
            return super.onTouchEvent(event);
        }
    }
}

完整代碼

自定義屬性

<resources>
    <declare-styleable name="DownloadProgressView">
        <!-- 進(jìn)度條背景 -->
        <attr name="dpv_bg" format="color" />
        <!-- 已有進(jìn)度條背景 -->
        <attr name="dpv_progress_bg" format="color" />
        <!-- 百分比字體顏色 -->
        <attr name="dpv_percentage_text_color" format="color" />
        <!-- 上層百分比字體顏色 -->
        <attr name="dpv_percentage_text_color2" format="color" />
        <attr name="dpv_percentage_text_size" format="integer|float|dimension|reference" />
        <!-- 當(dāng)前進(jìn)度值 -->
        <attr name="dpv_progress" format="integer" />
        <!-- 最大進(jìn)度值 -->
        <attr name="dpv_max_progress" format="integer" />
        <!-- 控制模式 -->
        <attr name="dpv_control_mode" format="enum">
            <enum name="normal" value="1" />
            <enum name="touch" value="2" />
        </attr>
    </declare-styleable>
</resources>

自定義View

public class DownloadProgressView extends View {
    /**
     * 控制模式-普通
     */
    private static final int MODE_NORMAL = 1;
    /**
     * 控制模式-觸摸
     */
    private static final int MODE_TOUCH = 2;

    /**
     * View默認(rèn)最小寬度
     */
    private int mDefaultMinWidth;
    /**
     * View默認(rèn)最小高度
     */
    private int mDefaultMinHeight;

    /**
     * 控件寬
     */
    private int mViewWidth;
    /**
     * 控件高
     */
    private int mViewHeight;

    /**
     * 圓角弧度
     */
    private float mRadius;
    /**
     * 背景畫筆
     */
    private Paint mBgPaint;
    /**
     * 進(jìn)度畫筆
     */
    private Paint mProgressPaint;
    /**
     * 文字畫筆
     */
    private Paint mTextPaint;
    /**
     * 當(dāng)前進(jìn)度
     */
    private int mProgress;
    /**
     * 背景顏色
     */
    private int mBgColor;
    /**
     * 進(jìn)度背景顏色
     */
    private int mProgressBgColor;
    /**
     * 進(jìn)度百分比文字的顏色
     */
    private int mPercentageTextColor;
    /**
     * 第二層進(jìn)度百分比文字的顏色
     */
    private int mPercentageTextColor2;
    /**
     * 進(jìn)度百分比文字的字體大小
     */
    private float mPercentageTextSize;
    /**
     * 最大進(jìn)度值
     */
    private int mMaxProgress;
    /**
     * 進(jìn)度更新監(jiān)聽
     */
    private OnProgressUpdateListener mOnProgressUpdateListener;
    /**
     * 控制模式
     */
    private int mControlMode;
    /**
     * 按下時(shí)Down事件的x坐標(biāo)
     */
    private float mTouchDownX;

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

    public DownloadProgressView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DownloadProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs, defStyleAttr);
    }

    private void init(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        initAttr(context, attrs, defStyleAttr);
        //取消硬件加速
        setLayerType(LAYER_TYPE_SOFTWARE, null);
        //背景畫筆
        mBgPaint = new Paint();
        mBgPaint.setAntiAlias(true);
        mBgPaint.setColor(mBgColor);
        //進(jìn)度畫筆
        mProgressPaint = new Paint();
        mProgressPaint.setColor(mProgressBgColor);
        mProgressPaint.setAntiAlias(true);
        //文字畫筆
        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextSize(mPercentageTextSize);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
        //計(jì)算默認(rèn)寬、高
        mDefaultMinWidth = dip2px(context, 180f);
        mDefaultMinHeight = dip2px(context, 40f);
    }

    private void initAttr(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.DownloadProgressView, defStyleAttr, 0);
        mBgColor = array.getColor(R.styleable.DownloadProgressView_dpv_bg, Color.argb(100, 169, 169, 169));
        mProgressBgColor = array.getColor(R.styleable.DownloadProgressView_dpv_progress_bg, Color.GRAY);
        //進(jìn)度百分比文字的顏色,默認(rèn)和進(jìn)度背景顏色一致
        mPercentageTextColor = array.getColor(R.styleable.DownloadProgressView_dpv_percentage_text_color, mProgressBgColor);
        //第二層,進(jìn)度百分比文字的顏色
        mPercentageTextColor2 = array.getColor(R.styleable.DownloadProgressView_dpv_percentage_text_color2, Color.WHITE);
        //進(jìn)度百分比文字的字體顏色
        mPercentageTextSize = array.getDimension(R.styleable.DownloadProgressView_dpv_percentage_text_size, sp2px(context, 15f));
        //當(dāng)前進(jìn)度值
        mProgress = array.getInt(R.styleable.DownloadProgressView_dpv_progress, 0);
        //最大進(jìn)度值
        mMaxProgress = array.getInteger(R.styleable.DownloadProgressView_dpv_max_progress, 100);
        //控制模式
        mControlMode = array.getInt(R.styleable.DownloadProgressView_dpv_control_mode, MODE_NORMAL);
        array.recycle();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mViewWidth = w;
        mViewHeight = h;
        //計(jì)算出圓角半徑
        mRadius = Math.min(mViewWidth, mViewHeight) / 2f;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //裁剪圓角
        clipRound(canvas);
        //畫背景
        drawBg(canvas);
        //畫進(jìn)度條
        drawProgress(canvas);
        //畫文字圖層
        drawText(canvas);
    }

    //------------ getFrameXxx()方法都是處理padding ------------

    private float getFrameLeft() {
        return getPaddingStart();
    }

    private float getFrameRight() {
        return mViewWidth - getPaddingEnd();
    }

    private float getFrameTop() {
        return getPaddingTop();
    }

    private float getFrameBottom() {
        return mViewHeight - getPaddingBottom();
    }

    //------------ getFrameXxx()方法都是處理padding ------------

    /**
     * 裁剪圓角
     */
    private void clipRound(Canvas canvas) {
        Path path = new Path();
        RectF roundRect = new RectF(getFrameLeft(), getFrameTop(), getFrameRight(), getFrameBottom());
        path.addRoundRect(roundRect, mRadius, mRadius, Path.Direction.CW);
        canvas.clipPath(path);
    }

    /**
     * 畫背景
     */
    private void drawBg(Canvas canvas) {
        canvas.drawRect(new RectF(getFrameLeft(), getPaddingTop(), getFrameRight(), getFrameBottom()), mBgPaint);
    }

    /**
     * 畫進(jìn)度
     */
    private void drawProgress(Canvas canvas) {
        RectF rect = new RectF(getFrameLeft(), getFrameTop(), getFrameRight() * getProgressRatio(), getFrameBottom());
        canvas.drawRect(rect, mProgressPaint);
    }

    /**
     * 畫文字
     */
    private void drawText(Canvas canvas) {
        mTextPaint.setColor(mPercentageTextColor);
        //創(chuàng)建文字圖層
        Bitmap textBitmap = Bitmap.createBitmap(mViewWidth, mViewHeight, Bitmap.Config.ARGB_8888);
        Canvas textCanvas = new Canvas(textBitmap);
        String textContent = mProgress + "%";
        //計(jì)算文字Y軸坐標(biāo)
        float textY = mViewHeight / 2.0f - (mTextPaint.getFontMetricsInt().descent / 2.0f + mTextPaint.getFontMetricsInt().ascent / 2.0f);
        textCanvas.drawText(textContent, mViewWidth / 2.0f, textY, mTextPaint);
        //畫最上層的白色圖層,未相交時(shí)不會(huì)顯示出來
        mTextPaint.setColor(mPercentageTextColor2);
        mTextPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
        textCanvas.drawRect(new RectF(getFrameLeft(), getFrameTop(), getFrameRight() * getProgressRatio(), getFrameBottom()), mTextPaint);
        //畫結(jié)合后的圖層
        canvas.drawBitmap(textBitmap, getFrameLeft(), getFrameTop(), mTextPaint);
        mTextPaint.setXfermode(null);
        textBitmap.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(handleMeasure(widthMeasureSpec, true), handleMeasure(heightMeasureSpec, false));
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        int action = event.getAction();
        //攔截事件,然后讓父類不進(jìn)行攔截
        if (mControlMode == MODE_TOUCH && action == MotionEvent.ACTION_DOWN) {
            getParent().requestDisallowInterceptTouchEvent(true);
            return true;
        }
        return super.dispatchTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //拽托模式下才起效果
        if (mControlMode == MODE_TOUCH) {
            int action = event.getAction();
            //包裹Down事件時(shí)的x坐標(biāo)
            if (action == MotionEvent.ACTION_DOWN) {
                mTouchDownX = event.getX();
                return true;
            } else if (action == MotionEvent.ACTION_MOVE || action == MotionEvent.ACTION_UP) {
                //Move或Up的時(shí)候,計(jì)算拽托進(jìn)度
                float endX = event.getX();
                //計(jì)算公式:百分比值 = 移動(dòng)距離 / 總長度
                float distanceX = Math.abs(endX - mTouchDownX);
                float ratio = (distanceX * 1.0f) / (getFrameRight() - getFrameLeft());
                //計(jì)算百分比應(yīng)該有的進(jìn)度:進(jìn)度 = 總進(jìn)度 * 進(jìn)度百分比值
                float progress = mMaxProgress * ratio;
                setProgress((int) progress);
                return true;
            }
            return super.onTouchEvent(event);
        } else {
            return super.onTouchEvent(event);
        }
    }

    /**
     * 處理MeasureSpec
     */
    private int handleMeasure(int measureSpec, boolean isWidth) {
        int result;
        if (isWidth) {
            result = mDefaultMinWidth;
        } else {
            result = mDefaultMinHeight;
        }
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else {
            //處理wrap_content的情況
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
            }
        }
        return result;
    }

    /**
     * 設(shè)置進(jìn)度最大值
     */
    public DownloadProgressView setMaxProgress(int maxProgress) {
        mMaxProgress = maxProgress;
        invalidate();
        return this;
    }

    /**
     * 設(shè)置進(jìn)度
     */
    public void setProgress(int progress) {
        if (progress >= 0 && progress <= 100) {
            mProgress = progress;
            invalidate();
            if (mOnProgressUpdateListener != null) {
                mOnProgressUpdateListener.onProgressUpdate(progress);
            }
        }
    }

    /**
     * 獲取當(dāng)前進(jìn)度
     */
    public int getProgress() {
        return mProgress;
    }

    /**
     * 獲取最大進(jìn)度
     */
    public int getMaxProgress() {
        return mMaxProgress;
    }

    public interface OnProgressUpdateListener {
        /**
         * 進(jìn)度更新時(shí)回調(diào)
         *
         * @param progress 當(dāng)前進(jìn)度
         */
        void onProgressUpdate(int progress);
    }

    public void setOnProgressUpdateListener(OnProgressUpdateListener onProgressUpdateListener) {
        mOnProgressUpdateListener = onProgressUpdateListener;
    }

    /**
     * 獲取當(dāng)前進(jìn)度值比值
     */
    private float getProgressRatio() {
        return (mProgress / (mMaxProgress * 1.0f));
    }

    public static int sp2px(Context context, float spValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }

    public static int dip2px(Context context, float dipValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }
}

具體使用

在布局中添加控件

<com.zh.cavas.sample.widget.DownloadProgressView
        android:id="@+id/download_progress"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_marginStart="20dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="20dp"
        app:dpv_bg="#E6EAFB"
        app:dpv_max_progress="100"
        app:dpv_percentage_text_color2="@color/white"
        app:dpv_percentage_text_size="14sp"
        app:dpv_progress="0"
        app:dpv_progress_bg="#3548FE"
        tools:dpv_progress="50" />

Java代碼

private DownloadProgressView vDownloadProgressView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        vDownloadProgressView = view.findViewById(R.id.download_progress);
        //設(shè)置進(jìn)度監(jiān)聽
        vDownloadProgressView.setOnProgressUpdateListener(new DownloadProgressView.OnProgressUpdateListener() {
            @Override
            public void onProgressUpdate(int progress) {
                vProgressIndicator.setText("當(dāng)前進(jìn)度:" + progress);
            }
        });
        //手動(dòng)設(shè)置當(dāng)前進(jìn)度
        vDownloadProgressView.setProgress(0);
        //設(shè)置最大值
        vDownloadProgressView.setMaxProgress(100);
    }
}

到這里就結(jié)束啦。

以上就是Android實(shí)現(xiàn)下載進(jìn)度條效果的詳細(xì)內(nèi)容,更多關(guān)于Android 下載進(jìn)度條的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Android編程開發(fā)之EditText實(shí)現(xiàn)輸入QQ表情圖像的方法

    Android編程開發(fā)之EditText實(shí)現(xiàn)輸入QQ表情圖像的方法

    這篇文章主要介紹了Android編程開發(fā)之EditText實(shí)現(xiàn)輸入QQ表情圖像的方法,涉及Android多媒體文件及EditText的相關(guān)操作技巧,需要的朋友可以參考下
    2015-12-12
  • 詳解Android應(yīng)用中preference首選項(xiàng)的編寫方法

    詳解Android應(yīng)用中preference首選項(xiàng)的編寫方法

    這篇文章主要介紹了Android應(yīng)用中preference首選項(xiàng)的編寫方法,或許Apple將其翻譯為'偏好設(shè)置'更直觀些,即用戶對(duì)應(yīng)用的一些個(gè)性化調(diào)整菜單,需要的朋友可以參考下
    2016-04-04
  • Android開發(fā)教程之ContentProvider數(shù)據(jù)存儲(chǔ)

    Android開發(fā)教程之ContentProvider數(shù)據(jù)存儲(chǔ)

    這篇文章主要介紹了Android開發(fā)教程之ContentProvider數(shù)據(jù)存儲(chǔ)的相關(guān)資料,需要的朋友可以參考下
    2016-12-12
  • 常見Android選項(xiàng)菜單樣式集合

    常見Android選項(xiàng)菜單樣式集合

    這篇文章主要為大家分享了一份屬于你自己的常見Android菜單樣式集合,方便大家開發(fā)使用Android菜單,對(duì)OptionMenu感興趣的小伙伴們可以參考一下
    2016-02-02
  • 詳解Android類加載ClassLoader

    詳解Android類加載ClassLoader

    本篇文章主要介紹了詳解Android類加載ClassLoader,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-04-04
  • Android組件初始化三種方式小結(jié)

    Android組件初始化三種方式小結(jié)

    在Android中,組件的初始化通常需要在適當(dāng)?shù)纳芷诜椒ㄖ羞M(jìn)行,本文給大家詳細(xì)的介紹了初始化的三種方式,文中有詳細(xì)的代碼示例供大家參考,具有一定的參考價(jià)值,需要的朋友可以參考下
    2023-08-08
  • android桌面懸浮窗顯示錄屏?xí)r間控制效果

    android桌面懸浮窗顯示錄屏?xí)r間控制效果

    這篇文章主要為大家詳細(xì)介紹了android桌面懸浮窗,顯示錄屏?xí)r間控制效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • Android Tablayout 自定義Tab布局的使用案例

    Android Tablayout 自定義Tab布局的使用案例

    這篇文章主要介紹了Android Tablayout 自定義Tab布局的使用案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • Android?Flutter繪制扇形圖詳解

    Android?Flutter繪制扇形圖詳解

    在開發(fā)過程中通常會(huì)遇到一些不規(guī)則的UI,比如不規(guī)則的線條,多邊形,統(tǒng)計(jì)圖表等等,用那些通用組件通過組合的方式無法進(jìn)行實(shí)現(xiàn),這就需要我們自己進(jìn)行繪制。本文將利用Flutter繪制扇形圖,感興趣的可以學(xué)習(xí)一下
    2022-05-05
  • Android Cocos Creator游戲開發(fā)平臺(tái)打包優(yōu)化實(shí)現(xiàn)方案

    Android Cocos Creator游戲開發(fā)平臺(tái)打包優(yōu)化實(shí)現(xiàn)方案

    Cocos Creator是一款輕量、高效、免費(fèi)開源的跨平臺(tái)游戲引擎,同時(shí)也是實(shí)時(shí)3D內(nèi)容創(chuàng)作平臺(tái),不僅支持2D、3D的游戲開發(fā),同時(shí)在HMI、IoT、XR、虛擬人偶等領(lǐng)域,均可提供一套完善的行業(yè)解決方案
    2022-11-11

最新評(píng)論

浙江省| 邹平县| 大荔县| 广宗县| 清丰县| 万州区| 保德县| 宿松县| 青神县| 丹巴县| 视频| 兴国县| 云南省| 金门县| 邻水| 田林县| 林芝县| 屯门区| 庆阳市| 通榆县| 镇江市| 蛟河市| 固阳县| 金秀| 灵台县| 西贡区| 博乐市| 武功县| 富平县| 当阳市| 鸡泽县| 屯留县| 柏乡县| 浦县| 盐城市| 永昌县| 双峰县| 甘南县| 桐梓县| 庄河市| 泸定县|