当前位置: 首页 > news >正文

时间轴、流程类时间轴绘制

效果图

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

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

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

流程类时间轴效果图

思路

关于ItemDecoration相关的内容已经写了不少,如果看过以前的文章自定义ItemDecoration分割线的高度、颜色、偏移,看完这个你就懂了、Android购物车效果实现(RecyclerView悬浮头部实现)

这个其实就是小菜一碟。我们需要做的工作有两点

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

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

在这里插入图片描述

具体实现

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

步骤一:ItemView顶部偏移

 override fun getItemOffsets(outRect: Rect,view: View,parent: RecyclerView,state: RecyclerView.State,) {if (parent.getChildAdapterPosition(view) != 0) {//第一个不做顶部偏移outRect.top = topItemSpace}outRect.left = leftItemSpace}

步骤二:绘制圆和线条

override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {//获取到的是当前屏幕可见的个数val childCount = parent.childCountfor (i in 0 until childCount) {val view = parent.getChildAt(i)//获取真实的在整体数据中的位置val index=parent.getChildAdapterPosition(view)//ItemView左侧+偏移的矩形框(绿色框部分)val spaceRectTop = if (index == 0) view.top else view.top - topItemSpaceval spaceRectBottom = view.bottomval spaceRectLeft = view.left - leftItemSpaceval spaceRectRight = view.left//ItemView左侧,不包含偏移的矩形框(红色框部分)val dataRectLeft = view.left - leftItemSpaceval dataRectTop = view.topval dataRectRight = view.leftval dataRectBottom = view.bottom//圆心坐标var centerX = if(isDrawAtMiddle) (dataRectLeft + dataRectRight)/ 2  else (dataRectLeft + dataRectRight)/ 2 + circleLeftPaddingval centerY =if (isDrawAtMiddle) (dataRectTop + dataRectBottom) / 2 else dataRectTop + circleRadius + circleTopPadding//绘制第一条线if (index==0){if (isDrawFirstItemTopLine){c.drawLine(centerX.toFloat(),spaceRectTop.toFloat(),centerX.toFloat(),(centerY - circleRadius).toFloat(),mLinePaint)}}else{c.drawLine(centerX.toFloat(),spaceRectTop.toFloat(),centerX.toFloat(),(centerY - circleRadius).toFloat(),mLinePaint)}//绘制圆(居中显示)c.drawCircle(centerX.toFloat(), centerY.toFloat(), circleRadius.toFloat(), mCirclePaint)//绘制第二条线,注意这里要用itemCount,因为上面的childCount是当前页面可见的个数parent.adapter?.let {if (index!=it.itemCount-1){c.drawLine(centerX.toFloat(),(centerY + circleRadius).toFloat(),centerX.toFloat(),spaceRectBottom.toFloat(),mLinePaint)}else{if (isDrawLastItemBottomLine){c.drawLine(centerX.toFloat(),(centerY + circleRadius).toFloat(),centerX.toFloat(),spaceRectBottom.toFloat(),mLinePaint)}}}}}

注意:下标的获取

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

流程类的绘制

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

override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {...val srcRect = Rect(0, 0, progressBitmap.width, progressBitmap.height)val dstRect = Rect(centerX - circleRadius,centerY - circleRadius,centerX + circleRadius,centerY + circleRadius)c.drawBitmap(errorBitmap, srcRect, dstRect, mCirclePaint)...
}

总结

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

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

相关文章:

  • 7-1RT-Thread邮箱
  • LabVIEW在高校中的应用
  • 技术干货分享:初识分布式版本控制系统Git
  • 大学专业选择的岔路口:计算机相关专业的前景与适配性
  • DBSCAN 算法【python,机器学习,算法】
  • Web前端职业描述:编织数字世界的绚丽画卷
  • 360数字安全:2024年4月勒索软件流行态势分析报告
  • MySQL常用命令(Linux环境)
  • 2024年,计算机相关专业还值得选择吗?
  • 如何实现观察者模式和发布-订阅模式?
  • 高压电工作业历年试题分享(含答案)
  • web鼠标前端设置:深入探索与个性化定制
  • 不是所有的硬盘柜都叫“安全专家”,但它做到了!
  • Lua - 魔兽世界SRP6网站源码(FastWeb)
  • Nginx05-负载均衡详解、LNMP+NFS、会话保持、负载均衡状态检查upstream-check、平滑升级
  • 【Amaple教程】5. 插件
  • Idea+maven+scala构建包并在spark on yarn 运行
  • JS创建对象模式及其对象原型链探究(一):Object模式
  • Odoo domain写法及运用
  • Puppeteer:浏览器控制器
  • Python socket服务器端、客户端传送信息
  • SAP云平台运行环境Cloud Foundry和Neo的区别
  • Vim 折腾记
  • Webpack4 学习笔记 - 01:webpack的安装和简单配置
  • 工作手记之html2canvas使用概述
  • 互联网大裁员:Java程序员失工作,焉知不能进ali?
  • 计算机常识 - 收藏集 - 掘金
  • 技术:超级实用的电脑小技巧
  • 盘点那些不知名却常用的 Git 操作
  • 设计模式 开闭原则
  • 世界上最简单的无等待算法(getAndIncrement)
  • hi-nginx-1.3.4编译安装
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • ​1:1公有云能力整体输出,腾讯云“七剑”下云端
  • ​如何使用ArcGIS Pro制作渐变河流效果
  • #pragma pack(1)
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • (7)STL算法之交换赋值
  • (9)目标检测_SSD的原理
  • (C#)一个最简单的链表类
  • (k8s)Kubernetes本地存储接入
  • (二)Kafka离线安装 - Zookeeper下载及安装
  • (五)activiti-modeler 编辑器初步优化
  • (转)linux 命令大全
  • (转)Oracle 9i 数据库设计指引全集(1)
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .NET 8.0 中有哪些新的变化?
  • .net 受管制代码
  • .secret勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复
  • @CacheInvalidate(name = “xxx“, key = “#results.![a+b]“,multi = true)是什么意思
  • [ C++ ] STL---string类的使用指南
  • [ Python ]使用Charles对Python程序发出的Get与Post请求抓包-解决Python程序报错问题