前言:之前有个需求是做一个播放的进度条,于是我在网上查找了一些文章,发现最终还是出入较大,没办法,还是自己写吧。

先贴2张效果图:

Android 设置视频内显示进度条 视频播放进度条_提示框

Android 设置视频内显示进度条 视频播放进度条_提示框_02

当然了,我们产品的要求可不是这么简单,得是进度条的左上角显示播放视频的名称,右上角显示播放的总时长。但实现到这一步了,其他那2个需求就太简单了。

难点嘛,你们看了设计图可能觉得没难点,但是当时对我来说就有一个难点,那就是绘制的字体在提示框的中间,查询了一些文章才做成最终效果。

绘制文字的代码如下:

private void drawProgressText2(Canvas canvas){
        textRect.left = (int) moveDistance;
        textRect.top = paintWidth+progressMarginTop+triangleHeight;
        textRect.right = (int) (tipWidth + moveDistance);
        textRect.bottom = tipHeight+paintWidth+progressMarginTop+triangleHeight;
        Paint.FontMetricsInt fontMetrics = textPaint.getFontMetricsInt();
        int baseline = (textRect.bottom + textRect.top - fontMetrics.bottom - fontMetrics.top) / 2;
        //文字绘制到提示框的中心位置
        canvas.drawText(progressText, textRect.centerX(), baseline, textPaint);
    }

其中:moveDistance 表示提示框的最左边的值;paintWidth表示绘制进度条的宽度,progressMarginTop 表示 整个提示框距离进度条的距离,triangleHeight表示绘制小三角指示的高度;tipWidth 表示提示框的宽度啦。还有一点设置绘制文字的piant d的setTextAlign(Paint.Align.CENTER),这样文字就居中显示啦。

然后就是绘制小三角,代码如下:

private void drawTriangle2(Canvas canvas) {
        path.moveTo(moveDistance + tipWidth / 2, paintWidth+progressMarginTop);
        path.lineTo(moveDistance + tipWidth / 2-triangleHeight/2, paintWidth+progressMarginTop+triangleHeight);
        path.lineTo(moveDistance + tipWidth / 2+triangleHeight/2, paintWidth+progressMarginTop+triangleHeight);
        canvas.drawPath(path, tipPaint);
        path.reset();
    }

这个就没啥好说的,就是先设定三角顶尖的位置,然后分别向左、右绘制一条直线,设置paint 的 style 为 Paint.Style.FILL就填满了小三角。

然后是绘制圆角矩形,有现成的api调用:

private void drawRoundRect2(Canvas canvas) {
        rectF.set(moveDistance, paintWidth+progressMarginTop+triangleHeight, tipWidth + moveDistance, paintWidth+progressMarginTop+triangleHeight+tipHeight);
        canvas.drawRoundRect(rectF, roundRectRadius, roundRectRadius, tipPaint);
    }

这个很简单就不BB了,最后是画进度条,先画一个背景,然后画进度。

private void drawProgress2(Canvas canvas){
        canvas.drawLine(getPaddingLeft(), 0, getWidth(), 0, bgPaint);
        canvas.drawLine(getPaddingLeft(), 0, currentProgress, 0, progressPaint);
    }

然后就是模拟动画了:

private void  initAnimation(){
        progressAnimator = ValueAnimator.ofFloat(0, mProgress);
        progressAnimator.setDuration(10*1000);
        progressAnimator.setStartDelay(500);
        progressAnimator.setInterpolator(new LinearInterpolator());

        progressAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                float value = (float) valueAnimator.getAnimatedValue();
//                progressText = String.valueOf((int)value);
                progressText = getTime((int)value);

                //把当前百分比进度转化成view宽度对应的比例
                currentProgress = value * mViewWidth / mProgress;
                //移动进度提示框,只有当前进度到提示框中间位置之后开始移动,
                //当进度框移动到最右边的时候停止移动,但是进度条还可以继续移动
                //moveDis是tip框移动的距离
                if (currentProgress >= (tipWidth / 2) &&
                        currentProgress <= (mViewWidth - tipWidth / 2)) {
                    moveDistance = currentProgress - tipWidth / 2;
                }
                invalidate();
            }
        });

        progressAnimator.start();
    }

这里面都解释清楚了,最后记得设置 mProgress 这个变量额值:

/**
     * 设置最大进度
     * @param progress
     */
    public void setProgress(int progress){
        mProgress = progress;
        initAnimation();
    }

好了,就说到这里了,有问题欢迎指正。