教程:响应式实时搜索

教程:响应式实时搜索

今天的客座教程由 Corona 大使、俄勒冈州波特兰市的应用程序开发人员 Ed Maurina 友情提供。Ed 是每周 Corona Geek 聚会的常客,也是 Corona 社区的活跃成员。他为 REEL FX Studios 开发了游戏,并维护他的 Corona SSK 游戏开发库。在 RoamingGamer.com 查看他的作品和博客。


在本教程中,我们将讨论一种简单的技术,您可以使用该技术来实现实时数据搜索,并在您的应用程序中产生响应式反馈和更新。

挑战

如果您曾经尝试实现实时搜索,您就会意识到,对于大型数据集和/或动态变化的搜索条件,很难保持应用程序的响应性。

例如,您的应用程序可能具有以下要求

  • 该应用程序具有庞大的数据集。
  • 该数据集需要可搜索。
  • 当用户开始输入搜索条件时,需要立即执行搜索。
  • 当搜索条件更改时,搜索应自动实时调整。
  • 匹配的条目在找到时会返回,更新应用程序界面。
  • 应用程序应保持响应。

最后一个要求至关重要。如果您的应用程序在执行搜索时出现挂起或临时故障,您最好不要分发它。

那么,如何做到这一点?

示例应用程序

为了演示上述一般问题的解决方案,让我指定一个确切的应用程序,然后提供解决该问题的代码。

该应用程序将具有以下功能

  • 大型数据集 — 一个包含 100,000 多个单词的简单单词列表。
  • FPS 计数器 — 将始终显示一个简单的 FPS 计数器,以提供响应性的具体证明。
  • 搜索字段 — 一个文本输入字段(在设备和两个模拟器中都有效)。
  • 进度计数器 — 用于显示总单词数、已找到的单词数和当前搜索索引的仪表。
  • 结果列表 — 一个基本的(不可滚动列表),用于显示找到的单词。

应用程序模块

示例代码 具有多个模块,这些模块位于同名的 Lua 文件中

  • common.lua — 计算和发现有用的变量和标志(leftrightcenterXonSimulator 等)。
  • wordList.lua — 生成数据集。
  • meter.lua — 创建一个帧速率仪表。
  • searchField.lua — 为我们的搜索创建一个“文本输入字段”,该字段在设备和两个模拟器上都有效(还会创建计数和索引计数器)。
  • example.lua — 本文开头提出的问题的解决方案。

初始化搜索设置

在启动 "enterFrame" 监听器之前,我们需要初始化模块

  1. 创建和定位初始结果显示组。
  2. 将标志和变量初始化为起始值。
  3. 设置每帧允许执行的比较次数。

请注意,在步骤 3 中,当我们初始化搜索代码时,如果我们没有指定特定时间,代码会自动检测 FPS(如 config.lua 中设置的),然后计算等于一帧一半的时间。

“enterFrame” 监听器

初始化模块后,我们可以定义 "enterFrame" 监听器并开始运行它。该定义有五个部分。

第 1 部分 — 获取当前搜索词,并查看它是否已更改

如果搜索结果已更改,我们会重置搜索结果(类似于模块初始化),记下新的搜索词,并设置标志,指示我们正在“搜索”。如果它们没有更改,我们只需忽略这段代码并继续。

第 2 部分 — 如果未“搜索”则中止

如果 searching 标志设置为 false,我们会提前中止并等待下一帧重新开始。

第 3 部分 — 搜索直到时间耗尽,或到达单词列表末尾

虽然以上每个模块都可能有用且有趣,但我们将只关注 example.lua

解决方案

在构建之后,您可能会失望地发现这基本上是一个自我调节的 "enterFrame" 监听器。简而言之,每当搜索条件更改时,监听器就会启动新的搜索,并在一个紧密的循环中搜索,直到经过设定的时间。然后它停止搜索并退出。在下一帧,整个序列再次开始。

监听器具有以下逻辑结构

Responsive Real-time Searching Logic Flowchart

现在让我们看一下实际代码。

这段代码

  • 本地化了一些有用的函数以提高执行速度。
  • 记录了 startTime
  • elapsedTime 设置为零。
  • 进入搜索循环,只有当到达列表末尾或超时时才会退出。
  • 一旦找到匹配项,代码会显示它,然后继续。

这是解决方案的核心,您应该理解,通过每次搜索并(可能)显示结果时测量“经过的时间”,我们可以确保

  1. 搜索可以尽快给出结果,而不会阻塞当前帧的完成。
  2. 停止和恢复搜索的代码是动态的,并考虑了搜索和显示结果的成本。

第 4 部分 — 更新搜索索引标签

请注意,这部分纯粹是为了示例中的反馈

第 5 部分 — 检查是否已到达列表末尾,如果是则退出

作为监听器的最后一步,我们检查是否已到达单词列表的末尾。 如果是,我们将 searching 设置为 false。 在任何情况下,我们都会退出该函数(它将在下一帧的开头再次执行)。

结论

正如我上面提到的,这篇博文附带示例代码,请在您自己的应用程序中进行实验。 希望本教程向您展示了一种在您的项目中实现实时、响应式搜索的有趣方法。


标签
,
Charles McKeever
[email protected]

Charles McKeever 是一位终身计算机极客,他喜欢探索各种技术,以了解它们的工作原理、如何将它们组合在一起,以及如何利用它们来推动创业活动。

6 条评论
  • Lerg
    发布于 15:05, 5 月 12 日

    好东西。它也可以与 SQLite 一起使用。您只需使用 SQL 和 LIMIT 关键字将表循环替换为小的增量搜索即可。

  • Erich Grüttner D.
    发布于 07:35, 5 月 13 日

    像往常一样,Ed,干得好!
    谢谢!!!

  • Andrzej // Futuretro 工作室
    发布于 11:52, 5 月 13 日

    很棒的教程,绝对会参考它。谢谢!

  • Mario
    发布于 17:17, 5 月 13 日

    是的!我实现了 Erich 提到的 sqlite 版本。 效果很好。 有很多方法可以解决一个常见问题。 感谢这篇文章!!

    -Mario

  • Andreas
    发布于 05:26, 9 月 5 日

    您好
    示例代码的链接似乎已损坏或已失效。
    有人可以帮我找到示例吗?
    谢谢 Andreas