TextField 的 Flutter Cursor 在 setState 后移动到位置 0

Flutter Cursor of TextField moves to Position 0 after setState

我想在 TextFields 文本更改时在文本中显示一些内容:

class _MyPageState extends State<MyPage> {

String name;

@override
  Widget build(BuildContext context) {
      TextEditingController c = new TextEditingController(text: name);
      c.addListener(() {
         setState(() { name = c.text;});
      });
      return Scaffold(
         body: Center(
            child: Column(children: [ 
               Text('Hello, ' + name + '!'),
               TextField(controller: c)
      ])));
  }
}

文本按预期更新,但问题是每次输入字符时文本字段的光标移动到位置 0。

我已经修改了你的代码,你只需要改变你的 TextEditingController 见下文。

class _MyPageState extends State<MyWidget> {
  // initialize to empty string
  String name = "";
  
 @override
  Widget build(BuildContext context) {
    // this is how textEditingController should be
    final TextEditingController c = TextEditingController.fromValue(
            new TextEditingValue(
                text: name,
                selection: new TextSelection.collapsed(
                    offset: name.length)));
    
    c.addListener(() {
         setState(() { name = c.text;});
      });
    
      return Scaffold(
         body: Center(
            child: Column(children: [ 
               Text('Hello, ' + name + '!'),
               TextField(controller: c)
      ])));
  }
}

问题是您每次重建小部件时都会创建一个新的 TextEditingController。正在根据键入的每个字符重建小部件。

您只需将 TextEditingController 移到小部件构建函数之外。并将 c.addListener 移至小部件的 initState 函数。这样 TextEditingController 只创建一次,监听器只添加一次。

PS: 处理widget的时候把你的controller也处理一下就好了

class MyPage extends StatefulWidget {
  @override
  _MyPageState createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {
  String name = '';
  TextEditingController c = new TextEditingController();

  @override
  void initState() {
    c.addListener(() {
      setState(() {
        name = c.text;
      });
    });
    super.initState();
  }

  @override
  void dispose() {
    c.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
            child: Column(children: [
      Text('Hello, ' + name + '!'),
      TextField(controller: c)
    ])));
  }
}