没用seekbar或者progressbar原生控件,通过绘制实现。只讲下有用的思想,无关属性不解释,也不用看。
主要看onDraw方法代码:
绘制背景线,canvas.drawRect线绘制了第一条线,因为需要渐变,可以看到canvas.drawPath是从第一条线之后开始算left的,ringht包含整个进度条的长度。
// 背景线
if (mNodeIndex != mNodeNum - 1) {
LinearGradient gradient = new LinearGradient(0, 0, mGap,
0, Color.WHITE, mContext.getResources().getColor(R.color.color_E5E5E5), Shader.TileMode.CLAMP);
Paint paint = new Paint();
paint.setShader(gradient);
canvas.drawRect(paddingLeft, (getHeight() - mLineWidth) / 2, mStartX + mGap, (getHeight() + mLineWidth) / 2, paint);
mNormalPath.addRect(mStartX + mGap, (getHeight() - mLineWidth) / 2, endX - mGap, (getHeight() + mLineWidth) / 2, Path.Direction.CCW);
canvas.drawPath(mNormalPath, mNormalPaint);
}
然后循环绘制圆球盖在对应的位置
// 背景节点
for (int i = 0; i < mNodeNum; i++) {
if (i <= mNodeIndex) {
continue;
}
if (i != 0 && i != mNodeNum - 1) {
canvas.drawCircle(mStartX + (mGap * i), getHeight() / 2, mNormalNodeRadius, mNormalCirclePaint);
}
}
再绘制进度的线,也是第一条线的长度渐变
// 选中线
if (mNodeIndex > 0 && mNodeIndex != mNodeNum - 1) {
LinearGradient gradient = new LinearGradient(0, 0, mGap,
0, Color.WHITE, mContext.getResources().getColor(R.color.color_FD5344), Shader.TileMode.CLAMP);
Paint paint = new Paint();
paint.setShader(gradient);
canvas.drawRect(paddingLeft, (getHeight() - mLineWidth) / 2, mStartX + mGap, (getHeight() + mLineWidth) / 2, paint);
mSelectedPath.addRect(mStartX + mGap, (getHeight() - mLineWidth) / 2, mStartX + mGap * mNodeIndex, (getHeight() + mLineWidth) / 2, Path.Direction.CCW);
}
最后绘制选中的,也就是进度颜色的圆圈。
// 选中节点
for (int i = 0; i <= mNodeIndex; i++) {
if (i != 0 && i != mNodeNum - 1)
mSelectedPath.addCircle(mStartX + mGap * i, getHeight() / 2, mSelectedNodeRadius, Path.Direction.CCW);
}
canvas.drawPath(mSelectedPath, mSelectedPaint);
然后是怎么让上下的图片和文字与对应阶段的圆圈居中对齐:
public void alignmentPosition(View view, int width, int height, int i) {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(width, height);
params.leftMargin = mStartX + mGap * i - view.getMeasuredWidth() / 2;
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
view.setLayoutParams(params);
}
public void alignmentPositionTextView(View view, int i) {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.leftMargin = mStartX + mGap * i - view.getMeasuredWidth() / 2;
view.setLayoutParams(params);
}
图片是通过第一个方法,textview通过的第二个方法。将view传进来,然后按照绘制时候的addCirle计算left的方式,对view设置LayoutParams指定marginleft减去view本身宽度的一半即可居中对齐进度条中的圆圈。
没啥可说的,似乎都是基础,希望对你有可以借鉴的地方。