前言:之前有个需求是做一个播放的进度条,于是我在网上查找了一些文章,发现最终还是出入较大,没办法,还是自己写吧。
先贴2张效果图:
当然了,我们产品的要求可不是这么简单,得是进度条的左上角显示播放视频的名称,右上角显示播放的总时长。但实现到这一步了,其他那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();
}
好了,就说到这里了,有问题欢迎指正。