skip to Main Content

I have a textfield in flutter as follows:

Widget build(BuildContext context) {
    return TextField(
      maxLines: null,
      onChanged: (value) {
        print(value);
      },
      autofocus: false,
      controller: smcontroller,
      textDirection: TextDirection.rtl,
      textAlignVertical: TextAlignVertical.center,
      style: const TextStyle(
        color: Color(0xffffffff),
      ),
      decoration: InputDecoration(
        hintText: AppLocalizations.translate('Type a message'),
        hintTextDirection: TextDirection.rtl,
      ),
    );
  }

When I type hellošŸ¤© in the textfield, the textfield correctly shows "šŸ¤©hello". But the value on onChanged callback shows "hellošŸ¤©" and the controller also has same value. I want the controller to also have "šŸ¤©hello".

2

Answers


  1. The directionality of the output from the print function depends on how you set up the terminal. If you have correctly set up the Flutter widgets to use RTL directionality, whether through the Directionality widget or the textDirection property of TextField, you don’t need to worry about the reversed output from the terminal.

    Login or Signup to reply.
  2. The issue you’re encountering with Flutter’s TextField widget is due to the behavior of text direction and how it affects the onChanged callback and the controller’s value. Hereā€™s how you can ensure that both the displayed text and the controller’s value reflect the correct order of characters:

    Problem Explanation

    Text Direction and Display: Setting TextDirection.rtl correctly displays the text in right-to-left order visually, which is why "šŸ¤©hello" appears correctly as "šŸ¤©hello" in the UI.

    Controller and onChanged Callback: The onChanged callback and the controller both reflect the actual text value as entered, without considering the visual order. This is because they store the raw text input without adjusting for display direction.

    Solution

    To ensure that both the onChanged callback and the controller’s value reflect the displayed order of text ("šŸ¤©hello"), you can manually adjust the text before setting it to the controller. Hereā€™s how you can achieve this:

    import 'package:flutter/material.dart';
    
    class MyTextField extends StatefulWidget {
      @override
      _MyTextFieldState createState() => _MyTextFieldState();
    }
    
    class _MyTextFieldState extends State<MyTextField> {
      final TextEditingController smcontroller = TextEditingController();
    
      @override
      Widget build(BuildContext context) {
        return TextField(
          maxLines: null,
          onChanged: (value) {
            // Value passed here is raw input value, so adjust it before setting to controller
            String adjustedValue = adjustTextDirection(value);
            smcontroller.value = smcontroller.value.copyWith(
              text: adjustedValue,
              selection: TextSelection.collapsed(offset: adjustedValue.length),
            );
            print(smcontroller.text); // Should print "šŸ¤©hello"
          },
          autofocus: false,
          controller: smcontroller,
          textDirection: TextDirection.rtl,
          textAlignVertical: TextAlignVertical.center,
          style: const TextStyle(
            color: Color(0xffffffff),
          ),
          decoration: InputDecoration(
            hintText: "Type a message",
            hintTextDirection: TextDirection.rtl,
          ),
        );
      }
    
      String adjustTextDirection(String value) {
        // Ensure the displayed text is in the correct order
        if (value.isEmpty) {
          return value;
        }
    
        // Check if the first character is an emoji
        final firstCodeUnit = value.codeUnitAt(0);
        if (firstCodeUnit >= 0xd800 && firstCodeUnit <= 0xdbff) {
          // This is a surrogate pair, indicating an emoji
          return value;
        }
    
        // Reverse the text for correct display order
        return value.split('').reversed.join('');
      }
    
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search