前段时间在项目中遇到一个自定义控件,需要实现拖动一个类似SeekBar的东西来选择时间段。花费了一些时间和精力搞了出来。效果图如下

具体的代码和注释在源码中都有,这里只贴出关键代码
关键代码
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
String measureHeight = "获取文本高度";
paint.getTextBounds(measureHeight, 0, measureHeight.length(), textound);
timeheight = textound.height() + marginText + blockHeight + marginTimeBlock + seekBarHeight;
/** * 高度为时间控件所需的高度,宽度占满屏幕宽度 */
setMeasuredDimension(timeWidth, timeheight);
}
@Override
protected void onDraw(Canvas canvas) {
//绘制不可能选择的时间块
if (disSelectBlock != null && disSelectBlock.size() > 0) {
Rect rect = new Rect(0,0,blockWidth,blockHeight)
RectF rectf = new RectF()
rectf.top = marginText + textound.height()
rectf.bottom = textound.height() + blockHeight
BitmapFactory.Options options = new BitmapFactory.Options()
options.outWidth = blockWidth
options.outHeight = blockHeight
Bitmap notSelectBg = BitmapFactory.decodeResource(getResources(),R.drawable.time_disselect_bg,options)
for (int i = 0
rectf.left =disSelectBlock.get(i) * blockWidth
rectf.right = disSelectBlock.get(i) * blockWidth+blockWidth
canvas.drawBitmap(notSelectBg,rect,rectf,null)
}
}
//绘制文字
paint.setColor(getResources().getColor(R.color.white))
int time = beginTime
int lineStartY = 0
int lineEndX = textound.height() + blockHeight
for (int i = 0
if (i % 2 == 0) {
String timeText = time + "时"
paint.getTextBounds(timeText, 0, timeText.length(), textound)
canvas.drawText(timeText, blockWidth + blockWidth * i - textound.height(), textound.height(), paint)
time++
//短的分割线的起始纵坐标
lineStartY = textound.height() + blockHeight / 2
} else {
//长的分割线的起始纵坐标
lineStartY = textound.height()
}
lineStartY += marginText
//绘制时间块分割线
canvas.drawLine(blockWidth * i, lineStartY, blockWidth * i, lineEndX, paint)
}
//绘制最后端的一条分割短线
canvas.drawLine(timeWidth, lineStartY + blockHeight / 2, timeWidth, lineEndX, paint)
paint.setStrokeWidth(1)
paint.setColor(getResources().getColor(R.color.gray))
//绘制拖动条顶部的线条
canvas.drawLine(0, timeheight - seekBarHeight, timeWidth, timeheight - seekBarHeight, paint)
//绘制拖动条底部的线条
paint.setStrokeWidth(2)
canvas.drawLine(0, timeheight, timeWidth - 2, timeheight - 2, paint)
if (seekBarStart != 0) {
//绘制拖动条尾部
paint.setStrokeWidth(0)
paint.setColor(getResources().getColor(R.color.color_fabe00))
int disNum = seekBarEnd - seekBarStart
int startX = seekBarStart * blockWidth + bodyDistance
if (startX < blockWidth) {
startX = blockWidth
} else if (startX > timeWidth - blockWidth - disNum * blockWidth) {
startX = timeWidth - blockWidth - disNum * blockWidth
}
int endX = seekBarEnd * blockWidth + moveDistance + bodyDistance
if (endX > timeWidth - blockWidth) {
endX = timeWidth - blockWidth
} else if (bodyDistance != 0 && endX < startX + blockWidth * disNum) {
endX = startX + blockWidth * disNum
} else if (endX < startX + blockWidth) {
endX = startX + blockWidth
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
canvas.drawRoundRect(startX, timeheight - seekBarHeight + 10, endX, timeheight - 10, 4, 4, paint)
} else {
canvas.drawRect(startX, timeheight - seekBarHeight + 10, endX, timeheight - 10, paint)
}
//绘制拖动条头部圆圈
paint.setColor(getResources().getColor(R.color.color_eb7938))
canvas.drawCircle(endX, timeheight - seekBarHeight / 2, seekBarHeight / 2, paint)
paint.setColor(getResources().getColor(R.color.white))
canvas.drawCircle(endX, timeheight - seekBarHeight / 2, seekBarHeight / 4, paint)
}
}
——————————————————————
源码地址