背景
需求改了,上一个样式的进度条不要了! 对, 需求就是改的这么快这么突然, 能怎么办继续改呗
效果
步骤
1.获取控件的宽高
还是继续在onMeasure
中获取控件宽高
PS:如果使用onMeasure获取控件宽高就必须手动调用
setMeasuredDimension
方法设置宽高否则会报错
@Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//获取控件宽高
width = MeasureSpec.getSize(widthMeasureSpec);
height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width, height);
}
2.获取文字宽度
由于要画文字,就会涉及到获取文字宽度的问题,这里使用measureText()
方法获取文字的实际宽度(如果涉及到Padding,则需要按照实际情况加上左右的距离)
float textWidth = paintWave.measureText(text);
3.绘制文字边界问题
在控件中绘制文字特别是这个文字还会跟着进度走, 就肯定会涉及到文字画出边界的问题, 这里就简单处理一下,条件是 X轴坐标 + 文字高度 是否大于控件宽度
int progress = getProgress();
float location = width / 100 * progress;
float textWidth = paintWave.measureText(progress + "%");
//如果文字初始坐标小于0,则x轴赋值为文字宽度,因为在绘制文字是会减去文字的宽度
if ((location - textWidth) <= 0){
location = textWidth;
}
//如果文字移动坐标大于控件宽度,则x轴赋值为控件宽度,因为在绘制文字是会减去文字的宽度
if ((location + textWidth) >= width){
location = width;
}
//此处x轴减文字宽度是为了防止在进度为100时文字画出控件边界
canvas.drawText(progress + "%", location - textWidth, (height >> 1) + paintWave.getTextSize() * 3, paintWave);
4.绘制圆点滑块
绘制圆点滑块时的注意事项和逻辑同绘制文字, 都是要处理边界问题
5.控制文字进度位置
考虑到可能由于需求问题, 导致进度文字有可能出现在进度条上方或者下方,于是加了个属性进行控制
<declare-styleable name="SliderProgressBarStyle">
//文字位置
<attr name="textLocation">
<enum name="bottom" value="0"/>
<enum name="top" value="1"/>
</attr>
//是否显示气泡
<attr name="isShowBubble" format="boolean" />
</declare-styleable>
文字位置默认是在进度条下方,气泡默认不显示, 根据设置的文字位置去计算对应的Y轴坐标
if (textLocation == 0){
textY = (height >> 1) - paintWave.getTextSize() * 2;
}else{
textY = (height >> 1) + paintWave.getTextSize() * 2;
}
6. 气泡
处理气泡时需要注意几点
1.本身气泡图标中的边距
2.绘制气泡时两边可能会超出控件边界
3.绘制气泡时坐标位置
if (isShowBubble) {
//防止在边界时气泡绘制有问题, 做了一个控件最大宽度判断, 是否为气泡改变方向
if ((location + bubbleLeftWidth) >= width){
canvas.drawText(progress + "%", location - bubbleRightWidth /2 - textWidth / 2, height / 2 - bubbleRightHeight / 2, paintWave);
canvas.drawBitmap(bubbleRight, location - bubbleRightWidth , height / 2 - bubbleRightHeight, null);
}else {
canvas.drawText(progress + "%", location + bubbleLeftWidth / 4 - textWidth / 2, height / 2 - bubbleLeftHeight / 2, paintWave);
canvas.drawBitmap(bubbleLeft, location - bubbleLeftWidth / 4, height / 2 - bubbleLeftHeight, null);
}
}else {
//此处x轴减文字宽度是为了防止在进度为100时文字画出控件边界
canvas.drawText(progress + "%", location - textWidth, textY, paintWave);
}