【问题标题】:Flutter - TextField is empty every time I re-open the widgetFlutter - 每次我重新打开小部件时 TextField 都是空的
【发布时间】:2021-04-27 15:58:01
【问题描述】:

所以,我是 Flutter 的新手,正在尝试编写一个简单的笔记应用程序来学习如何解决它。该应用程序的布局是一个HomePage 和一个NoteTiles 的ListView,当点击它时打开一个相应的NotePage,您可以在其中写下东西。我遇到的问题是,每次我离开NotePage 然后从HomePage 重新打开它时,NotePage 都会丢失其内容。
我的第一个想法是将内容保留在相应的NoteTile 中,这样当我离开NotePage 时,我会弹出内容,并在需要时将之前保存的内容推送到NotePage。问题是我没有找到任何简单的方法来推送和设置内容。我已经看到有 Notification 和 Route 方法,但它们带有相当多的样板文件,它们看起来更像是用于将数据从子级传递给父级,我可以在弹出时轻松完成。
那么,有没有办法避免NotePage的内容被重置呢?或者也许有一种简单的方法可以initState 之前保存的内容?
这是我到目前为止的代码:

class NoteTile extends ListTile {

  final NotePage note;
  final Text title;
  final BuildContext context;

  NoteTile(this.title, this.note, this.context) : super(
    title: title,
    onTap: () => {
      Navigator.of(context).push(
        MaterialPageRoute(builder: (context) => note),
      ),
    },
    onLongPress: () => null,
    );

  void switchToNote() async {
    Navigator.of(context).push(
      MaterialPageRoute(builder: (context) => note),
    );
  }

}

onLongPress 稍后将用于删除备注。

class NotePage extends StatefulWidget {
  final String title;
  NotePage({Key key, this.title}) : super(key: key);

  @override
  _NotePageState createState() => _NotePageState();
}

class _NotePageState extends State<NotePage> {
  TextEditingController _controller;
  String _value;

  void initState() {
    super.initState();
    _controller = TextEditingController();
    _controller.addListener(_updateValue);
    _value = '';
  }

  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  void _updateValue(){
    _value = _controller.text;
  }

  Future<bool> _onWillPop() async {
    Navigator.pop(context, _value);
    return true;
  }

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
        child: Scaffold(
          appBar: AppBar(
            title:  Text(widget.title),
          ),
          body: Container(
            child: TextField(
              decoration: InputDecoration(
                border: InputBorder.none,
                hintStyle: TextStyle(fontStyle: FontStyle.italic),
                hintText: 'New note',
              ),
              maxLines: null,
              controller: _controller,
            ),
            padding: EdgeInsets.all(12.0),
          ),
        ),
        onWillPop: _onWillPop,
    );
  }
}

_onWillPop 是将内容发回给NoteTile,目前它忽略了返回数据,因为我稍后再次推送NotePage 时未能找到使用该数据的方法。

【问题讨论】:

    标签: flutter state textfield


    【解决方案1】:

    ListTileStatelessWidget 小部件,所以不能保留状态,NoteTile 应该是StatefulWidget

    这是NoteTile的示例:

    class NoteTile extends StatefulWidget {
      final Text title;
    
      const NoteTile({Key key, this.title}) : super(key: key);
    
      @override
      State<StatefulWidget> createState() {
        return _NoteTileState();
      }
    }
    
    class _NoteTileState extends State<NoteTile> {
      String _result;
    
      @override
      void initState() {
        super.initState();
        _result = "";
      }
    
      void _onOpenNote() async {
        String result = await Navigator.of(context).push(
          MaterialPageRoute(builder: (context) => NotePage(title: _result)),
        );
        if (result != null) {
          _result = result;
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return ListTile(
          title: widget.title,
          onTap: _onOpenNote,
        );
      }
    }
    

    并且NotePage 应该在某些行中进行编辑:

    TextEditingController 可以有初始化字符串 & 必须由title 初始化:

    _controller = TextEditingController(text: widget.title);
    

    Navigator.pop 可以发布结果,你做对了,但是如果你想得到结果,应该等待Navigator.of(context).push,因为它在另一个线程中运行。

    【讨论】:

    • 非常感谢,现在这更有意义了!我宁愿不使用 NotePage 的 title 字段来传递内容,但我想在 NotePage 中添加一个附加字段就足够了
    猜你喜欢
    • 2021-05-30
    • 2019-08-23
    • 2023-03-18
    • 2019-07-12
    • 1970-01-01
    • 2020-06-23
    • 1970-01-01
    • 1970-01-01
    • 2014-11-10
    相关资源
    最近更新 更多