Create a Japanese Kana EditableText in Flutter
It's a bit tricky to comment without seeing any of the code, but let's see..
So, I had this solution set up in Javascript, and just ported it over to Flutter. Hope this helps out. This works for me regardless of whether or not the cursor was at the end when the typing began.
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)
);
The first four lines are just assignment, with line 1 converting from romaji to hiragana using whatever you have. tController is attached to the TextField. Here's the TextField:
TextField(
controller: tController,
onChanged: (text) => setText(text) /* calls the above code */
);
This doesn't hold onto the original romaji anywhere, in the same way that a Japanese IME wouldn't. Once a conversion is made, the old romaji is dropped, and only the Japanese remains.
I do not have the problems you describe, so this is? a solution to your issue.
Jpec
Updated on December 23, 2022Comments
-
Jpec over 1 year
I would like to create a romaji to kana converter EditableText. That is to say, by writing "saikou" in an EditableText, the displayed text should for instance be "さいこう".
Currently, I got this working if the user keeps writing without wanting to edit his text (but the cursor is placed at the beginning of the text and not at the end due to a bad offset).
But as soon as the user moves the TextSelection manually (by taping somewhere on the EditableText), the cursor is finally well positioned, BUT when he tries to edit the text (adding or removing a character) the wrong offset causes a mess.
Example:
The use wants to remove the "こ". He moves the cursor here (represented by the pipe): "さいこ|う".But when he will hit the delete key, the "い" character will disappear instead. This is due to the difference in length between the original text (saikou) and the japanese translation ("さいこう"). The original text length is 6, but the japanese length is only 4. By placing our cursor like this and hitting the "delete key", we will try to delete the 3rd caracter which is in the original text the letter "i" and not "こ" as in the japanese translation.
Idea
I can write a function that will match the original offset to the corresponding japanese offset. But this will only be useful if I can prevent the default text deletion from happening and programmatically update the text in consequence. However, I cannot find a way to prevent the deletion. I've already tried to use the onChange method on EditableText but despite trying to return in the function, the modification still occurs. I've also looked at the EditableText's Controller and try to change the text when the listener is triggered but it causes an infinite loop because of a change in state in this listener.
Any help will be really appreciated !
-
Jpec over 3 yearsHey, thank you very much for your comment. The
newPosition
seems to fix my issue along with the copyWith. I had also to change my conversion method not adapted to dynamic input by first, converting back to romaji the content. It's not optimal yet but it is now working ! Thank you again ! -
Jpec over 3 yearsBtw, it is worth mentioning that the composing value should be edited as well. Otherwise an exception is raised when the origLength is greater than the newLength. I've added composing: TextRange(0, newPosition) and it is working like a charm.
-
Admin over 3 yearsThanks! I'll toss that into mine as well!