【问题标题】:Flutter Cursor of TextField moves to Position 0 after setStateTextField 的 Flutter Cursor 在 setState 后移动到 Position 0
【发布时间】:2021-04-30 08:31:58
【问题描述】:

每当 TextFields 文本发生更改时,我想在 Text 中显示一些内容:

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

Text 会按预期更新,但问题是每次输入字符时 TextField 的光标都会移动到位置 0。

【问题讨论】:

    标签: flutter dart setstate


    【解决方案1】:

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

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

    PS:在处置小部件时处置您的控制器也很好

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

    【讨论】:

    • 是的,这是可行的,并且在构建方法中不初始化 TextController 是完全有意义的。非常感谢!
    • 我希望,我能给你 4-5 个赞。
    • 这个问题依然存在,即使在StatefulWidget开头实例化了控制器,review response。
    【解决方案2】:

    我已经修改了你的代码,你只需要改变你的 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)
          ])));
      }
    }
    

    【讨论】:

    • 效果很好,但有一个问题。如果用户将光标移动到特定位置以更改那里的内容,则在更改第一个字符后将光标移动到文本的末尾
    • 谢谢你,阿卡什。 c.dispose(); 时添加的监听器是否释放?叫什么?
    • 是的,监听器会处理
    • 我有多达 10 个控制器和监听器。有没有办法一次性把它们全部处理掉?
    猜你喜欢
    • 2020-12-08
    • 1970-01-01
    • 2019-10-10
    • 1970-01-01
    • 2012-12-14
    • 1970-01-01
    • 1970-01-01
    • 2021-05-13
    • 1970-01-01
    相关资源
    最近更新 更多