七爪源码:在 Flutter 中实现一个简单的拼写检查系统

拼写检查器很重要,因为您的应用程序具有可编辑的文本形式。 而且您不想在打字时依靠自己相信没有错误。 然后,拥有一个拼写检查器可以帮助您解决拼写错误的单词。

拼写检查系统主要由 Web、应用程序等引擎支持……例如,就像在带有 html 的 Web 中一样,我们有一个可编辑标签的枚举属性拼写检查。 对于 iOS 或 Android 本机,它们还具有 spellCheckingType 或 Spell checker 框架。 但不是在 Flutter 中,他们将拼写检查器设置为 Web 和应用程序的待办事项。

然后,在本文中,我将向您展示如何做一个简单的拼写检查系统,如果您不想等待 Flutter 团队,该系统可以很好地适用于您的应用程序。

正如您在此处看到的结果:

我将跳过在 Flutter 中初始化新应用程序的部分,直接进入重点。

我会分成2个部分:


1. 如何为可编辑文本小部件中的特定单词创建红色摆动下划线。

如果您查看 TextStyle 的文档,您会看到他们提到的有关为黑色文本创建波浪形红色下划线的部分。 通过这种方式,您可以通过转换为 TextSpan 为每个设置文本样式。

来吧,我们需要扩展一个自定义的TextEdittingController,我将它命名为CustomTextEdittingController,并给它一个属性listErrorTexts来存储所有需要红色下划线的单词。

现在,您需要通过检查 listErrorTexts 来覆盖 buildTextSpan 方法。 如果您的文本与 listErrorTexts 中的任何内容匹配,则为其提供自定义样式。 我使用由 Dart 语言支持的 splitMapJoin 将它们映射到多个 TextSpan 中。

import 'package:flutter/material.dart';

class CustomTextEdittingController extends TextEditingController {
  final List listErrorTexts;
  CustomTextEdittingController({String? text, this.listErrorTexts = const []})
      : super(text: text);

  @override
  TextSpan buildTextSpan(
      {required BuildContext context,
      TextStyle? style,
      required bool withComposing}) {
    final List children = [];
    if (listErrorTexts.isEmpty) {
      return TextSpan(text: text, style: style);
    }
    try {
      text.splitMapJoin(
          RegExp(r'\b(' + listErrorTexts.join('|').toString() + r')+\b'),
          onMatch: (m) {
        children.add(TextSpan(
          text: m[0],
          style: style!.copyWith(
              decoration: TextDecoration.underline,
              decorationStyle: TextDecorationStyle.wavy,
              decorationColor: Colors.red),
        ));
        return "";
      }, onNonMatch: (n) {
        children.add(TextSpan(text: n, style: style));
        return n;
      });
    } on Exception catch (e) {
      return TextSpan(text: text, style: style);
    }
    return TextSpan(children: children, style: style);
  }
}

记得把它们放在 try-catch 中,以防找不到匹配的。


2. 现在是时候实现拼写检查算法了

我称它为算法听起来有点神秘,但在这里我们只是简单地编写一个函数来检查每个输入的单词。

这个想法很简单,每次你输入单词并点击空格,然后你检查它之前的单词。 如果拼写错误,则添加到 listErrorTexts 中,否则您仍需要保存在缓存数组中,因此当该单词再次出现时,您无需再在字典中查找。

对于字典,你可以使用这个包 list_english_words 但对我来说,这个包有太多的单词(~380k 单词),而且对于普通的英语来说有很多多余的。 所以我得到了自己的列表,大约只有 84k 字。 (您可以在本文末尾找到它)。

我在一个单独的文件中创建了一个 TextFormField 小部件,并将一个名为 handleSpellCheck 的函数分配给 TextFormField 的 onChange 事件。

  void _handleOnChange(String text) {
    _handleSpellCheck(text, true);
  }

  void _handleSpellCheck(String text, bool ignoreLastWord) {
    if (!text.contains(' ')) {
      return;
    }
    final List arr = text.split(' ');
    if (ignoreLastWord) {
      arr.removeLast();
    }
    for (var word in arr) {
      if (word.isEmpty) {
        continue;
      } else if (_isWordHasNumberOrBracket(word)) {
        continue;
      }
      final wordToCheck = word.replaceAll(RegExp(r"[^\s\w]"), '');
      final wordToCheckInLowercase = wordToCheck.toLowerCase();
      if (!listTexts.contains(wordToCheckInLowercase)) {
        listTexts.add(wordToCheckInLowercase);
        if (!listEnglishWords.contains(wordToCheckInLowercase)) {
          listErrorTexts.add(wordToCheck);
        }
      }
    }
  }

  bool _isWordHasNumberOrBracket(String s) {
    return s.contains(RegExp(r'[0-9\()]'));
  }
  • ignoreLastWord 参数:它用于忽略您正在输入的最后一个单词。 仅当您点击空格时才会检查此单词。 如果您从其他地方粘贴一个段落并且您希望它也检查最后一个单词,则此参数很有用。
  • _isWordHasNumberOrBracket 函数:我们不会检查包含数字或括号的单词(例如:38timf,ew()),因为它可能会导致 TextEdittingController 中的正则表达式无法执行。 但如果你仍然想检查,你可以自己改进它。
  • wordToCheckInLowercase & wordToCheck:我创建了 2 个变量,一个小写的用于在字典中查找,另一个发送到我们的控制器并确保它突出显示正确的单词。

好的,现在您的拼写检查器可以按预期正常工作,但您可能想知道如果我们没有在末尾打任何空格,如何检查最后一个单词。

然后,您需要将 TextFormField 包装在 Focus 小部件中,以检测用户的鼠标是否失去焦点。

child: Focus(
  onFocusChange: (hasFocus) {
    if (!hasFocus) {
      _handleSpellCheck(_controller.text, false);
    }
  }
  child: TextFormField()
)

当您从其他地方粘贴段落时,您还需要在 initState 中调用此函数。 还有一个,如果你实现一个自定义的 TextFormField 并且可以在任何地方重复使用会更方便。 然后您需要在 initState() 中为您的 CustomTextEdittingController 分配默认值。


最后的想法

以上是创建拼写检查系统的非常简单的方法。 该算法是基本的,可能不是最好的方法。 我确实尝试测量执行时间,完成任务只需要大约 50~ 毫秒。

如果您对该算法有更好的方法或解决方案,请随时指出,我将不胜感激。

关注七爪网,获取更多APP/小程序/网站源码资源!

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章