让我更详细地描述一下问题。
- 您有一个可以绘制点和线条的表面,并且您知道如何使其看起来符合您的要求。
- 您有一个数据源,提供要绘制的点,并且该数据源会随时更改。
- 您希望表面尽可能准确地反映传入的数据。
第一个问题是-您的情况有什么缓慢之处?您知道延迟来自何处吗?首先,请确保您有一个要解决的问题;其次,请确保您知道问题来自何处。
假设您的问题在于数据大小,这个问题如何解决是一个复杂的问题。这取决于正在绘制的数据的属性-您可以假设什么不变量等等。您已经谈到了在float[]
中存储数据,因此我将假设您拥有一定数量的数据点,其值会发生变化。我还假设通过“100或1000”,您想表达的是“很多很多”,因为老实说,1000个浮点数并不是很多的数据。
当您有一个非常大的数组要绘制时,性能限制最终将来自于遍历数组。然后,您的性能增强将是减少您要遍历的数组量。这就是数据属性发挥作用的地方。
减少重绘操作量的一种方法是保留一个“脏列表”,它类似于Queue<Int>
。每当数组中的单元格更改时,将该数组索引入队,标记为“脏”。每次绘制方法回到时,出队脏列表中的固定数量条目,并仅更新与这些条目对应的渲染图像块-由于有那么多数据点,您可能拥有比屏幕像素更多的数据,因此您可能需要进行一些缩放和/或抗锯齿处理等。在任何给定的帧更新中重新绘制的条目数应受所需帧速率的限制-您可以根据先前绘制操作花费的时间以及脏列表的深度来使其自适应,以保持帧速率和可见数据年龄之间的良好平衡。
如果您尝试在屏幕上同时绘制所有数据,则此方法特别适用。如果您只查看数据的一部分(例如在可滚动视图中),并且数组位置与窗口大小之间存在某种对应关系,则可以“窗口化”数据-在每个绘制调用中,仅考虑实际在屏幕上的数据子集。如果您还有一个“缩放”功能,则可以混合使用这两种方法-这可能会变得复杂。
如果你的数据是窗口化的,每个数组元素的值决定了数据点是否在屏幕上,考虑使用一对排序列表,其中排序键是该值。这将让您在这种情况下执行上面概述的窗口化优化。如果窗口处理发生在两个维度中,您很可能只需要执行一个优化,但也有两个维度范围查询结构可以为您提供此功能。
假设我的固定数据大小的假设是错误的;相反,您正在向列表末尾添加数据,但现有数据点不会更改。在这种情况下,您最好使用类似于链接队列的结构,删除旧数据点而不是数组,因为增加数组大小往往会不必要地引入应用程序中的卡顿。
在这种情况下,您的优化是预先绘制一个跟随您的队列的缓冲区 - 当新元素进入队列时,将整个缓冲区向左移动并仅绘制包含新元素的区域。
如果问题是数据输入速率,则使用排队结构并跳过元素 - 在将它们添加到队列中时将其折叠,存储/绘制每个第n个元素或类似的内容。
如果渲染过程占用了所有时间,请考虑在后台线程上进行渲染并存储渲染图像。这将让您花费任意时间进行重绘 - 图表本身的帧率会降低,但整个应用程序的响应性不会下降。
Bitmap
/BitmapDrawable
支持的ImageView
。当出现新数据时,将其绘制在位图上,但不要清除旧数据,这样您就不需要每帧重新绘制所有内容。 - pelya