拼写检查器很重要,因为您的应用程序具有可编辑的文本形式。 而且您不想在打字时依靠自己相信没有错误。 然后,拥有一个拼写检查器可以帮助您解决拼写错误的单词。
拼写检查系统主要由 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\()]'));
}
好的,现在您的拼写检查器可以按预期正常工作,但您可能想知道如果我们没有在末尾打任何空格,如何检查最后一个单词。
然后,您需要将 TextFormField 包装在 Focus 小部件中,以检测用户的鼠标是否失去焦点。
child: Focus(
onFocusChange: (hasFocus) {
if (!hasFocus) {
_handleSpellCheck(_controller.text, false);
}
}
child: TextFormField()
)
当您从其他地方粘贴段落时,您还需要在 initState 中调用此函数。 还有一个,如果你实现一个自定义的 TextFormField 并且可以在任何地方重复使用会更方便。 然后您需要在 initState() 中为您的 CustomTextEdittingController 分配默认值。
最后的想法
以上是创建拼写检查系统的非常简单的方法。 该算法是基本的,可能不是最好的方法。 我确实尝试测量执行时间,完成任务只需要大约 50~ 毫秒。
如果您对该算法有更好的方法或解决方案,请随时指出,我将不胜感激。
关注七爪网,获取更多APP/小程序/网站源码资源!
留言与评论(共有 0 条评论) “” |