Search code examples
fluttertextdirection

flutter dynamic text directionality issue


code to reproduce error:

class TestWidget extends StatefulWidget {
  @override
  _TestWidgetState createState() => _TestWidgetState();
}

class _TestWidgetState extends State<TestWidget> {
  bool isRtl = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Directionality(
              child: TextField(),
              textDirection: isRtl ? TextDirection.rtl : TextDirection.ltr,
            ),
            RaisedButton(
              child: Text('click me!'),
              onPressed: () => setState(() => isRtl = !isRtl),
            ),
          ],
        ),
      ),
    );
  }
}

steps to reproduce:

  1. type 'some thing' into textfield
  2. remove it #it works fine
  3. click the button
  4. type 'سلام دنیا' into textfield
  5. try to remove it #see the error!

is there a workaround or fix for this error?


Solution

  • Solution 1. Set minLines to 1 and maxLines to null in the TextField:

    @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Column(
              mainAxisSize: MainAxisSize.max,
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Directionality(
                  child: TextField(
                    minLines: 1, // this is new
                    maxLines: null, // this is new
                  ),
                  textDirection: isRtl ? TextDirection.rtl : TextDirection.ltr,
                ),
                RaisedButton(
                  child: Text('click me!'),
                  onPressed: () => setState(() => isRtl = !isRtl),
                ),
              ],
            ),
          ),
        );
      }
    

    Solution 2. Remove the extra character that is inserted when tapping on space key in rtl:

      TextEditingController _textEditingController = TextEditingController();
      var isRtl = false;
      var _text = '';
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Column(
              mainAxisSize: MainAxisSize.max,
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Directionality(
                  textDirection: isRtl ? TextDirection.rtl : TextDirection.ltr,
                  child: TextFormField(
                    onChanged: (val) {
                      if (val.codeUnitAt(val.length - 1) == 8207 ||
                          val.codeUnitAt(val.length - 1) == 8206) {
                        setState(() {
                          _text = val.replaceAll(String.fromCharCode(8207), '');
                          _text = _text.replaceAll(String.fromCharCode(8206), '');
                          _textEditingController =
                          new TextEditingController.fromValue(
                              new TextEditingValue(
                                  text: _text,
                                  selection: new TextSelection.collapsed(
                                      offset: _text.length)));
                        });
                      }
                      else {
                        setState(() {
                          _text = val;
                        });
                      }
                    },
                    controller: _textEditingController,
                  ),
                ),
                RaisedButton(
                  child: Text('click me!'),
                  onPressed: () => setState(() {
                    isRtl = !isRtl;
                  }),
                ),
              ],
            ),
          ),
        );
      }