【问题标题】:How to set Initial value to a TextFormField on value received from previous screen in Flutter?如何在 Flutter 中从上一个屏幕收到的值上将初始值设置为 TextFormField?
【发布时间】:2019-12-05 21:07:03
【问题描述】:

在我的 react native 项目中,我在一页中有一个数据列表。然后单击列表中的每张卡片,我通过传递按下的卡片的值(如下面的代码)转到它们的详细信息页面-

Navigator.pushNamed(ctxt, '/DetailsNotes', arguments: _allNotes[index]);

之后,在下一个屏幕中,我会收到构建函数中的值,如下所示-

final ModelAllNotes args = ModalRoute.of(context).settings.arguments;

在这个屏幕中,我有两个 TextFormField 并在构建函数中初始化它们,如下所示-

final title = TextFormField(
  controller: _textFieldControllerTitle,
  keyboardType: TextInputType.emailAddress,
  autofocus: false,
  maxLength: 100,

  decoration: InputDecoration(
    hintText: 'Title',
    labelText: 'Title',

    icon: Icon(selectedIcons),
    contentPadding: EdgeInsets.fromLTRB(20.0, 20.0, 20.0, 20.0),
    border: OutlineInputBorder(borderRadius: BorderRadius.circular(10.0)),
  ),


  validator: (value) {
    if (value.isEmpty) {
      return 'Enter some text';
    }
    return null;
  },

  onSaved: (String value) {
    this._data.title = value;
  },

);

我还声明了 controlller 来处理 TextFormField 的文本更改和保存问题,如下所示-

   TextEditingController _textFieldControllerTitle = TextEditingController();

那么,现在的问题是——

我想从 args 变量中接收到的值中获得 TextFormField 的初始值,然后允许用户编辑 TextformFields。但是,每当我对每个 TextFormField 使用 initialValue 属性时,它都不起作用。

我需要一个解决方案来从 args(来自上一个屏幕)接收到值,然后最初在我的 TextFromField 中显示它们并保持它们可编辑。

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    一种选择是使用TextEditingController.fromValue(...)

    TextFormField(
      controller: TextEditingController.fromValue(
        TextEditingValue(
          text: arg,
          selection: TextSelection.collapsed(
            offset: arg.length,
          ),
        ),
      ),
    ),
    

    您可以通过连接各种侦听器和诸如此类的东西来检索或/和操作值,从而使其更复杂/更有用。

    为了查看它的实际效果,我在下面添加了一个最小的可运行示例。您的案例可能需要更多代码(也许dispose 和更强大的offset 处理),因为它仅用于说明目的。

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(Editable());
    }
    
    class Editable extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          initialRoute: '/',
          routes: {
            '/': (context) => FirstScreen(),
            '/second': (context) => SecondScreen(),
          },
        );
      }
    }
    
    class FirstScreen extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text('First Screen')),
          body: Center(
            child: RaisedButton(
              child: Text('To editable screen'),
              onPressed: () {
                Navigator.pushNamed(context, '/second', arguments: 'some value');
              },
            ),
          ),
        );
      }
    }
    
    class SecondScreen extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        String value = ModalRoute.of(context).settings.arguments;
        return Scaffold(
          appBar: AppBar(title: Text("Second Screen")),
          body: Center(
            child: Column(
              children: <Widget>[
                TextFormField(
                  controller: TextEditingController.fromValue(
                    TextEditingValue(
                      text: value,
                      selection: TextSelection.collapsed(offset: value.length),
                    ),
                  ),
                ),
                RaisedButton(
                  onPressed: () {
                    Navigator.pop(context);
                  },
                  child: Text('Back'),
                ),
              ],
            ),
          ),
        );
      }
    }
    

    【讨论】:

      【解决方案2】:

      试试这个:

      class ... extends State<...>{
      TextEditingController controller;
      
        @override
        void initState() {
          controller = TextEditingController();
          super.initState();
        }
      
        @override
        void didChangeDependencies() {
          final arg = ModalRoute.of(context).settings.arguments;
          controller.text = arg;
          super.didChangeDependencies();
        }
      
        @override
        void dispose() {
          controller.dispose();
          super.dispose();
        }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-06-19
        • 2021-04-01
        • 2017-05-20
        • 2020-06-14
        • 2019-08-01
        • 2020-10-18
        • 2022-11-18
        相关资源
        最近更新 更多