经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » 编程经验 » 查看文章
时间轴、流程类时间轴绘制
来源:cnblogs  作者:lidongRebirth  时间:2024/6/12 16:40:35  对本文有异议

效果图

时间轴效果图
  • 可控制是否绘制在中间
  • 控制绘制的线条是否为虚线
  • 控制第一条数据圆顶部线条和最后一条数据圆底部线条是否绘制

除了gif图片展示的属性,还可以控制圆的大小颜色、圆是否有上和左偏移、线条颜色等属性

除了通用的时间轴绘制,我们还可以通过改变绘制圆的样式,改为绘制相应的bitmap图像,来实现展示相关的流程

流程类时间轴效果图

思路

关于ItemDecoration相关的内容已经写了不少,这个其实就是小菜一碟。我们需要做的工作有两点

  • ItemDecoration在getItemOffsets()方法内做相应的偏移
  • onDraw()方法内分别绘制圆、圆顶部线条、圆底部线条
    • 绘制线条,我们需要知道start和end的点坐标;
    • 绘制圆,我们需要知道圆心和半径;

通过下图,你将能清楚地获取到这些绘制需要的一些信息

image

具体实现

有了以上内容,我们开始绘制

步骤一:ItemView顶部偏移

  1. override fun getItemOffsets(
  2. outRect: Rect,
  3. view: View,
  4. parent: RecyclerView,
  5. state: RecyclerView.State,
  6. ) {
  7. if (parent.getChildAdapterPosition(view) != 0) {
  8. //第一个不做顶部偏移
  9. outRect.top = topItemSpace
  10. }
  11. outRect.left = leftItemSpace
  12. }

步骤二:绘制圆和线条

  1. override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
  2. //获取到的是当前屏幕可见的个数
  3. val childCount = parent.childCount
  4. for (i in 0 until childCount) {
  5. val view = parent.getChildAt(i)
  6. //获取真实的在整体数据中的位置
  7. val index=parent.getChildAdapterPosition(view)
  8. //ItemView左侧+偏移的矩形框(绿色框部分)
  9. val spaceRectTop = if (index == 0) view.top else view.top - topItemSpace
  10. val spaceRectBottom = view.bottom
  11. val spaceRectLeft = view.left - leftItemSpace
  12. val spaceRectRight = view.left
  13. //ItemView左侧,不包含偏移的矩形框(红色框部分)
  14. val dataRectLeft = view.left - leftItemSpace
  15. val dataRectTop = view.top
  16. val dataRectRight = view.left
  17. val dataRectBottom = view.bottom
  18. //圆心坐标
  19. var centerX = if(isDrawAtMiddle) (dataRectLeft + dataRectRight)/ 2 else (dataRectLeft + dataRectRight)/ 2 + circleLeftPadding
  20. val centerY =
  21. if (isDrawAtMiddle) (dataRectTop + dataRectBottom) / 2 else dataRectTop + circleRadius + circleTopPadding
  22. //绘制第一条线
  23. if (index==0){
  24. if (isDrawFirstItemTopLine){
  25. c.drawLine(
  26. centerX.toFloat(),
  27. spaceRectTop.toFloat(),
  28. centerX.toFloat(),
  29. (centerY - circleRadius).toFloat(),
  30. mLinePaint
  31. )
  32. }
  33. }else{
  34. c.drawLine(
  35. centerX.toFloat(),
  36. spaceRectTop.toFloat(),
  37. centerX.toFloat(),
  38. (centerY - circleRadius).toFloat(),
  39. mLinePaint
  40. )
  41. }
  42. //绘制圆(居中显示)
  43. c.drawCircle(centerX.toFloat(), centerY.toFloat(), circleRadius.toFloat(), mCirclePaint)
  44. //绘制第二条线,注意这里要用itemCount,因为上面的childCount是当前页面可见的个数
  45. parent.adapter?.let {
  46. if (index!=it.itemCount-1){
  47. c.drawLine(
  48. centerX.toFloat(),
  49. (centerY + circleRadius).toFloat(),
  50. centerX.toFloat(),
  51. spaceRectBottom.toFloat(),
  52. mLinePaint
  53. )
  54. }else{
  55. if (isDrawLastItemBottomLine){
  56. c.drawLine(
  57. centerX.toFloat(),
  58. (centerY + circleRadius).toFloat(),
  59. centerX.toFloat(),
  60. spaceRectBottom.toFloat(),
  61. mLinePaint
  62. )
  63. }
  64. }
  65. }
  66. }
  67. }

注意:下标的获取

因为我们需要每个ItemView都绘制,所以需要使用循环。但因为val childCount = parent.childCount获取到的是当前页面可见的个数,并不是实际的个数,所以我们在判断是否是首条或者最后一条数据时,那个index要通过val index=parent.getChildAdapterPosition(view)的方式来获取到真实的下标位置。

流程类的绘制

和绘制通用的圆类似,不过是将Canvas.drawCircle()改为Canvas.drawBitmap()。至于不同的bitmap的加载,我们可以通过传入集合的数据类型来判断绘制哪种图片即可。

  1. override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
  2. ...
  3. val srcRect = Rect(0, 0, progressBitmap.width, progressBitmap.height)
  4. val dstRect = Rect(
  5. centerX - circleRadius,
  6. centerY - circleRadius,
  7. centerX + circleRadius,
  8. centerY + circleRadius
  9. )
  10. c.drawBitmap(errorBitmap, srcRect, dstRect, mCirclePaint)
  11. ...
  12. }

总结

其实主要还是ItemDecoration相关的内容,在onDraw()方法内绘制圆、绘制bitmap和绘制线条,根据上面的图,知道具体的坐标位置,绘制就很轻松了,也可以在此基础上继续扩展,使得我们的时间轴ItemDecoration更加的通用,方便运用到项目中。

如果本文对你有帮助,请别忘记三连,如果有不恰当的地方也请提出来,下篇文章见。
image

原文链接:https://www.cnblogs.com/myfittinglife/p/18244244

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号