在 Flutter 中创建日语假名 EditableText

Create a Japanese Kana EditableText in Flutter

我想创建一个罗马字到假名的转换器 EditableText。也就是说,通过在EditableText中写“saikou”,显示的文本应该是例如“さいこう”。

目前,如果用户继续写作而不想编辑他的,我就可以正常工作 文本(但由于偏移量错误,光标位于文本的开头而不是结尾)。

但是一旦用户手动移动 TextSelection(通过在 EditableText 的某处敲击),光标最终就定位好了,但是当他试图编辑文本(添加或删除字符)时,错误的偏移会导致一团糟

示例:

用户想去掉“こ”。他将光标移到此处(由管道表示):“さいこ|う”。但是当他按下删除键时,“い”字符将消失。这是由于原文 (saikou) 和日文翻译 ("さいこう") 之间的长度差异。原文长度为6,但日文长度只有4。通过这样放置我们的光标并点击“删除键”,我们将尝试删除原文中的第3个字符“i”而不是字母“i”日语翻译中的“こ”。

想法

我可以编写一个函数,将原始偏移量与相应的日文偏移量相匹配。但这只有在我可以防止发生默认文本删除并因此以编程方式更新文本时才有用。但是,我找不到防止删除的方法。 我已经尝试在 EditableText 上使用 onChange 方法,但尽管尝试在函数中使用 return,修改仍然发生。我还查看了 EditableText 的控制器,并尝试在触发侦听器时更改文本,但由于此侦听器中的状态发生变化,它会导致无限循环。

任何帮助将不胜感激!

在没有看到任何代码的情况下发表评论有点棘手,但让我们看看..

所以,我在 Javascript 中设置了这个解决方案,并将其移植到 Flutter 中。希望这会有所帮助。这对我有用,不管输入开始时光标是否在末尾。

final newText = convertFromRomaji(oldText);
final origPosition = tController.selection.start;
final origLength = oldText.length;
final newLength = newText.length;
final newPosition = newLength - (origLength - origPosition);

tController.value = tController.value.copyWith(
text: newText, 
selection : TextSelection(baseOffset : newPosition, extentOffset: newPosition)
);

前四行只是作业,第 1 行使用您拥有的任何内容将罗马字转换为平假名。 tController 附加到 TextField。这是文本字段:

TextField(
    controller: tController,
    onChanged: (text) => setText(text) /* calls the above code */
); 

这不会在任何地方保留原始罗马字,就像日语输入法一样。进行转换后,旧的罗马字将被删除,只剩下日文。

我没有你描述的问题,所以这是?解决您的问题。