The solution is to change text direction based on the first input character
Create a function that recognizes right-to-left characters using their code units (utf-16) and returns a TextDirection
representing the text direction of input language
TextDirection getDirection(String v) {
final string = v.trim();
if (string.isEmpty) return TextDirection.ltr;
final firstUnit = string.codeUnitAt(0);
if (firstUnit > 0x0600 && firstUnit < 0x06FF ||
firstUnit > 0x0750 && firstUnit < 0x077F ||
firstUnit > 0x07C0 && firstUnit < 0x07EA ||
firstUnit > 0x0840 && firstUnit < 0x085B ||
firstUnit > 0x08A0 && firstUnit < 0x08B4 ||
firstUnit > 0x08E3 && firstUnit < 0x08FF ||
firstUnit > 0xFB50 && firstUnit < 0xFBB1 ||
firstUnit > 0xFBD3 && firstUnit < 0xFD3D ||
firstUnit > 0xFD50 && firstUnit < 0xFD8F ||
firstUnit > 0xFD92 && firstUnit < 0xFDC7 ||
firstUnit > 0xFDF0 && firstUnit < 0xFDFC ||
firstUnit > 0xFE70 && firstUnit < 0xFE74 ||
firstUnit > 0xFE76 && firstUnit < 0xFEFC ||
firstUnit > 0x10800 && firstUnit < 0x10805 ||
firstUnit > 0x1B000 && firstUnit < 0x1B0FF ||
firstUnit > 0x1D165 && firstUnit < 0x1D169 ||
firstUnit > 0x1D16D && firstUnit < 0x1D172 ||
firstUnit > 0x1D17B && firstUnit < 0x1D182 ||
firstUnit > 0x1D185 && firstUnit < 0x1D18B ||
firstUnit > 0x1D1AA && firstUnit < 0x1D1AD ||
firstUnit > 0x1D242 && firstUnit < 0x1D244) {
return TextDirection.rtl;
}
return TextDirection.ltr;
}
Now wrap the TextField
inside a ValueListenableBuilder<TextDirection>
and change the text direction when changing text in text field:
class MyDynamicTextField extends StatelessWidget {
MyDynamicTextField({Key? key}) : super(key: key);
final ValueNotifier<TextDirection> _textDir =
ValueNotifier(TextDirection.ltr);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 40),
child: ValueListenableBuilder<TextDirection>(
valueListenable: _textDir,
builder: (context, value, child) =>
TextField(
textDirection: value,
onChanged: (input) {
if (input.trim().length < 2) {
final dir = getDirection(input);
if (dir != value) _textDir.value = dir;
}
},
),
),
),
),
);
}
}