如何正确地预填充颤动表单字段? [英] How to properly pre-fill flutter form field?

查看:61
本文介绍了如何正确地预填充颤动表单字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个编辑配置文件"页面,在该页面中,我将加载所有用户数据并让用户对其进行修改.但是,在TextEditingController上同时使用valuetext属性会导致无法修改TextFormField中的数据.我可以添加到它的开头,但是不能删除其中的任何字符.

I'm trying to create an "Edit Profile" page where I'm loading all the user data and letting the user modify it. However, using both the value and text properties on the TextEditingController result in being unable to modify the data in the TextFormField. I can add to the beginning of it, but I cannot delete any characters from it.

要进一步详细说明此行为,请在下面的屏幕截图中,我可以在该字段中键入更多内容(就像我做的"Asdf"一样),但是我不能从光标所在的位置向右移动光标或删除该光标. "F"或最初放置在此处的任何字符.

To elaborate on this behavior further, in the screenshot below, I can type more into the field (as I did the "Asdf"), but from where the cursor is, I cannot move the cursor to the right or delete the "F" or any of the characters placed there originally.

TextFormFieldOnSaved函数中,value参数是提交时表单的全文,在本例中为"AsdfFrederick".

In the OnSaved function of the TextFormField, the value param is the full text of the form at the time of submission, in this case, "AsdfFrederick".

这是我的代码:

import 'dart:async';
import 'package:flutter/material.dart';
import '../models/user.dart';

class EditProfileView extends StatefulWidget {
  @override
  _EditProfileViewState createState() => new _EditProfileViewState();
}

class _EditProfileViewState extends State<EditProfileView> {
  final GlobalKey<FormState> _formKey = new GlobalKey<FormState>();

  void _handleSubmitted() {
    final FormState form = _formKey.currentState;
    if (!form.validate()) {
    } else {
      form.save();
      User.instance.save().then((result) {
        print("Saving done: ${result}.");
        Navigator.pop(context);
      });
    }
  }


  @override
  Widget build(BuildContext context) {
    final ThemeData themeData = Theme.of(context);
    final DateTime today = new DateTime.now();

    // controllers for form text controllers
    final TextEditingController _firstNameController =
        new TextEditingController();
    //_firstNameController.value = new TextEditingValue(text: User.instance.first_name);
    _firstNameController.text = User.instance.first_name;
    final TextEditingController _lastNameController =
        new TextEditingController();
    _lastNameController.text = User.instance.last_name;

    return new Scaffold(
        appBar: new AppBar(title: const Text('Edit Profile'), actions: <Widget>[
          new Container(
              padding: const EdgeInsets.fromLTRB(0.0, 10.0, 5.0, 10.0),
              child: new MaterialButton(
                color: themeData.primaryColor,
                textColor: themeData.secondaryHeaderColor,
                child: new Text('Save'),
                onPressed: () {
                  _handleSubmitted();
                  Navigator.pop(context);
                },
              ))
        ]),
        body: new Form(
            key: _formKey,
            autovalidate: _autovalidate,
            onWillPop: _warnUserAboutInvalidData,
            child: new ListView(
              padding: const EdgeInsets.symmetric(horizontal: 16.0),
              children: <Widget>[
                new Container(
                  child: new TextFormField(
                    decoration: const InputDecoration(labelText: "First Name", hintText: "What do people call you?"),
                    autocorrect: false,
                    controller: _firstNameController,
                    onSaved: (String value) {
                      User.instance.first_name = value;
                    },
                  ),
                ),
                new Container(
                  child: new TextFormField(
                    decoration: const InputDecoration(labelText: "Last Name"),
                autocorrect: false,
                controller: _lastNameController,
                onSaved: (String value) {
                  User.instance.last_name = value;
                },
              ),
            ),
          ],
        )));
  }
}

这里是flutter doctor:

% flutter doctor
[✓] Flutter (on Mac OS X 10.12.6 16G29, locale en-US, channel alpha)
    • Flutter at /Users/frederickcook/flutter
    • Framework revision 701d534ba9 (2 weeks ago), 2017-09-12 14:01:51 -0700
    • Engine revision 31d03de019
    • Tools Dart version 1.25.0-dev.11.0

[✓] Android toolchain - develop for Android devices (Android SDK 26.0.0)
    • Android SDK at /Users/frederickcook/Library/Android/sdk
    • Platform android-26, build-tools 26.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_112-release-b06)

[✓] iOS toolchain - develop for iOS devices (Xcode 9.0)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 9.0, Build version 9A235
    • ios-deploy 1.9.2
    • CocoaPods version 1.2.1

[✓] Android Studio (version 2.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Java version OpenJDK Runtime Environment (build 1.8.0_112-release-b06)

[✓] IntelliJ IDEA Community Edition (version 2017.2.5)
    • Flutter plugin version 17.0
    • Dart plugin version 172.4155.35

[✓] Connected devices
    • iPhone 7 • 2AE532E3-5B4B-4D8D-8CFB-F54C3BF6F8EE • ios • iOS 11.0 (simulator)

推荐答案

弄清楚了:从TextFormField切换到TextField,创建了局部变量来存储对字段的更改,并使用initState设置了初始形式值而不是在build中完成操作.

Figured it out: switched from TextFormField to TextField, created local variables to store changes to the fields, and used initState to set initial form values instead of doing it in build.

import 'dart:async';
import 'package:flutter/material.dart';
import '../models/user.dart';

class EditProfileView extends StatefulWidget {
  @override
  _EditProfileViewState createState() => new _EditProfileViewState();
}

class _EditProfileViewState extends State<EditProfileView> {
  final GlobalKey<FormState> _formKey = new GlobalKey<FormState>();

  void _handleSubmitted() {
    final FormState form = _formKey.currentState;
    if (!form.validate()) {
      _autovalidate = true; // Start validating on every change.
      showInSnackBar('Please fix the errors in red before submitting.');
    } else {
      showInSnackBar('snackchat');
      User.instance.first_name = firstName;
      User.instance.last_name = lastName;

      User.instance.save().then((result) {
        print("Saving done: ${result}.");
      });
    }
  }

  // controllers for form text controllers
  final TextEditingController _firstNameController = new TextEditingController();
  String firstName = User.instance.first_name;
  final TextEditingController _lastNameController = new TextEditingController();
  String lastName = User.instance.last_name;

  @override
  void initState() {
    _firstNameController.text = firstName;
    _lastNameController.text = lastName;
    return super.initState();
  }

  @override
  Widget build(BuildContext context) {
    final ThemeData themeData = Theme.of(context);
    final DateTime today = new DateTime.now();

    return new Scaffold(
        appBar: new AppBar(title: const Text('Edit Profile'), actions: <Widget>[
          new Container(
              padding: const EdgeInsets.fromLTRB(0.0, 10.0, 5.0, 10.0),
              child: new MaterialButton(
                color: themeData.primaryColor,
                textColor: themeData.secondaryHeaderColor,
                child: new Text('Save'),
                onPressed: () {
                  _handleSubmitted();
                  Navigator.pop(context);
                },
              ))
        ]),
        body: new Form(
            key: _formKey,
            autovalidate: _autovalidate,
            onWillPop: _warnUserAboutInvalidData,
            child: new ListView(
              padding: const EdgeInsets.symmetric(horizontal: 16.0),
              children: <Widget>[
                new Container(
                  child: new TextField(
                    decoration: const InputDecoration(labelText: "First Name", hintText: "What do people call you?"),
                    autocorrect: false,
                    controller: _firstNameController,
                    onChanged: (String value) {
                      firstName = value;
                    },
                  ),
                ),
                new Container(
                  child: new TextField(
                    decoration: const InputDecoration(labelText: "Last Name"),
                    autocorrect: false,
                    controller: _lastNameController,
                    onChanged: (String value) {
                      lastName = value;
                    },
                  ),
                ),
              ],
            )));
  }
}

这篇关于如何正确地预填充颤动表单字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆