如何在 Flutter 中从上一个屏幕收到的值上将初始值设置为 TextFormField?

Posted

技术标签:

【中文标题】如何在 Flutter 中从上一个屏幕收到的值上将初始值设置为 TextFormField?【英文标题】:How to set Initial value to a TextFormField on value received from previous screen in Flutter? 【发布时间】: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 中显示它们并保持它们可编辑。

【问题讨论】:

【参考方案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();
  

【讨论】:

以上是关于如何在 Flutter 中从上一个屏幕收到的值上将初始值设置为 TextFormField?的主要内容,如果未能解决你的问题,请参考以下文章

如何在flutter中从firebase获取数据

如何在颤动中从另一个屏幕进行更改

如何在 React Native 中从一个屏幕导航到另一个屏幕?

在 C# 中从上到下连接两个数据表

Flutter中从api获取数据时出错

如何在 Swift 中从 NSDate 获取日、月和小时