颤振动态文本方向性问题

flutter dynamic text directionality issue

重现错误的代码:

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),
            ),
          ],
        ),
      ),
    );
  }
}

重现步骤:

  1. 在文本字段中输入 'some thing'
  2. 删除它 #它工作正常
  3. 点击按钮
  4. 在文本字段中输入“سلام دنیا”
  5. 尝试删除它 #see 错误!

是否有针对此错误的解决方法或修复方法?

解决方案1.TextField中将minLines设置为1,将maxLines设置为null

@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),
            ),
          ],
        ),
      ),
    );
  }

解决方案 2. 删除在 rtl 中点击 space 键时插入的额外字符:

  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;
              }),
            ),
          ],
        ),
      ),
    );
  }

我稍微修改了@Mobina的回答:

  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.value = TextEditingValue(
                        text: _text,
                        selection: TextSelection.collapsed(offset: _text.length),
                      ); //changed here!
                    });
                  }
                  else {
                    setState(() {
                      _text = val;
                    });
                  }
                },
                controller: _textEditingController,
              ),
            ),
            RaisedButton(
              child: Text('click me!'),
              onPressed: () => setState(() {
                isRtl = !isRtl;
              }),
            ),
          ],
        ),
      ),
    );
  }