可以将用户数据写入Firebase,可以';不要从火场读到田野:颤栗

可以将用户数据写入Firebase,可以';不要从火场读到田野:颤栗,firebase,flutter,google-cloud-firestore,flutter-change-notifier,change-notification,Firebase,Flutter,Google Cloud Firestore,Flutter Change Notifier,Change Notification,当用户试图编辑他们的信息时,我试图将我的用户数据读入表单字段。我可以向Firebase写入数据,但无法将用户数据读取和显示到内置字段中。为了区分,每个userData都以登录用户的mid作为userData的id进行存储 我错过了什么?下面是我的尝试 以下是我的UserData模型: class UserData { String id; String firstName; String lastName; String phoneNumber; String role;

当用户试图编辑他们的信息时,我试图将我的用户数据读入表单字段。我可以向Firebase写入数据,但无法将用户数据读取和显示到内置字段中。为了区分,每个userData都以登录用户的mid作为userData的id进行存储

我错过了什么?下面是我的尝试

以下是我的UserData模型:

class UserData {
  String id;
  String firstName;
  String lastName;
  String phoneNumber;
  String role;
  String businessName;
  String businessType;
  String streetAddress;
  String city;
  String state;
  String postcode;
  String country;
  String businessTradingCurrency;
  Timestamp createdAt;
  Timestamp updatedAt;

  UserData(
    this.id,
    this.firstName,
    this.businessTradingCurrency,
    this.businessType,
    this.businessName,
    this.city,
    this.country,
    this.createdAt,
    this.lastName,
    this.phoneNumber,
    this.postcode,
    this.role,
    this.state,
    this.streetAddress,
    this.updatedAt,
  );

  UserData.fromMap(Map<String, dynamic> data) {
    id = data['id'];
    firstName = data['first_name'];
    lastName = data['last_name'];
    phoneNumber = data['phone_number'];
    businessTradingCurrency = data['trading_currency'];
    role = data['role'];
    businessName = data['business_name'];
    businessType = data['business_type'];
    streetAddress = data['street_address'];
    city = data['city'];
    postcode = data['postcode'];
    state = data['state'];
    country = data['country'];
    createdAt = data['created_at'];
    updatedAt = data['updated_at'];
  }

  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'first_name': firstName,
      'last_name': lastName,
      'phone_number': phoneNumber,
      'role': role,
      'trading_currency': businessTradingCurrency,
      'business_name': businessName,
      'business_type': businessType,
      'street_address': streetAddress,
      'city': city,
      'postcode': postcode,
      'state': state,
      'country': country,
      'created_at': createdAt,
      'updated_at': updatedAt,
    };
  }
}
类用户数据{
字符串id;
字符串名;
字符串lastName;
字符串电话号码;
字符串角色;
字符串businessName;
字符串业务类型;
字符串地址;
字符串城市;
字符串状态;
字符串邮政编码;
弦国;
贸易货币;
时间戳createdAt;
时间戳更新数据;
用户数据(
这个身份证,
这个名字,
这是商业交易货币,
这是一种商业模式,
这是商业名称,
这个城市,
这个国家,
这个.createdAt,
这个姓,
这个电话号码,
这是邮政编码,
这个角色,,
这个州,
这是我的地址,
这个.updatedAt,
);
UserData.fromMap(地图数据){
id=数据['id'];
firstName=数据['first_name'];
lastName=data['last_name'];
phoneNumber=数据[‘电话号码’];
businessTradingCurrency=数据[“交易货币];
角色=数据['role'];
businessName=数据['business_name'];
businessType=data['business_type'];
streetAddress=数据['street_address'];
城市=数据[‘城市’];
邮政编码=数据[‘邮政编码’];
状态=数据[‘状态’];
国家=数据[‘国家’];
createdAt=data['created_at'];
updatedAt=数据['updated_at'];
}
映射toMap(){
返回{
“id”:id,
“名字”:名字,
“姓氏”:姓氏,
“电话号码”:电话号码,
“角色”:角色,
“交易货币”:业务交易货币,
“业务名称”:业务名称,
“业务类型”:业务类型,
“街道地址”:街道地址,
“城市”:城市,
“邮政编码”:邮政编码,
“国家”:国家,
"国":国,,
“created_at”:createdAt,
'updated_at':updatedAt,
};
}
}
下面是我的UserData通知程序类:

class UserDataNotifier with ChangeNotifier {
  UserData _currentLoggedInUserData;

  CollectionReference userDataRef = Firestore.instance.collection('userData');

  UserData get currentLoggedInUserData => _currentLoggedInUserData;

  set currentLoggedInUserData(UserData userData) {
    _currentLoggedInUserData = userData;
    notifyListeners();
  }

  Future<void> getUserData() async {
    String userId = (await FirebaseAuth.instance.currentUser()).uid.toString();
    DocumentSnapshot result =
        await Firestore.instance.collection('userData').document(userId).get();

    _currentLoggedInUserData = result.data as UserData;
    print('Phone Number: ${_currentLoggedInUserData.phoneNumber}');

    notifyListeners();
  }

  Future createOrUpdateUserData(UserData userData, bool isUpdating) async {
    String userId = (await FirebaseAuth.instance.currentUser()).uid;

    if (isUpdating) {
      userData.updatedAt = Timestamp.now();

      await userDataRef.document(userId).updateData(userData.toMap());
      print('updated userdata with id: ${userData.id}');
    } else {
      userData.createdAt = Timestamp.now();

      DocumentReference documentReference = userDataRef.document(userId);

      userData.id = documentReference.documentID;

      await documentReference.setData(userData.toMap(), merge: true);
      print('created userdata successfully with id: ${userData.id}');
    }
    notifyListeners();
  }
}
将UserDataNotifier与ChangeNotifier一起分类{
UserData _currentLoggedInUserData;
CollectionReference userDataRef=Firestore.instance.collection('userData');
UserData获取currentLoggedInUserData=>\u currentLoggedInUserData;
设置currentLoggedInUserData(UserData UserData){
_currentLoggedInUserData=用户数据;
notifyListeners();
}
未来的getUserData()异步{
字符串userId=(等待FirebaseAuth.instance.currentUser()).uid.toString();
文档快照结果=
等待Firestore.instance.collection('userData').document(userId.get();
_currentLoggedInUserData=result.data作为UserData;
打印('电话号码:${u currentLoggedInUserData.phoneNumber}');
notifyListeners();
}
未来的createOrUpdateUserData(UserData UserData,bool IsUpdate)异步{
字符串userId=(等待FirebaseAuth.instance.currentUser()).uid;
如果(正在更新){
userData.updatedAt=Timestamp.now();
等待userDataRef.document(userId.updateData(userData.toMap());
打印('updated userdata with id:${userdata.id}');
}否则{
userData.createdAt=Timestamp.now();
DocumentReference DocumentReference=userDataRef.document(用户ID);
userData.id=documentReference.documentID;
等待documentReference.setData(userData.toMap(),merge:true);
打印('id:${userdata.id}已成功创建userdata');
}
notifyListeners();
}
}
这是我的编辑用户配置文件表单:

class ProfileFormScreen extends StatefulWidget {
  static const String id = 'profile_form';

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

class _ProfileFormScreenState extends State<ProfileFormScreen> {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  UserData _currentLoggedInUserData;
  bool showSpinner = false;

  //global declarations
  String selectedBusinessTypeDropDownValue = 'Fashion';
  String selectedCurrencyDropDownValue = 'AUD: Australian Dollar';
  String selectedCountryDropDownValue = 'Australia';
  String email;

  @override
  void initState() {
    super.initState();

    UserDataNotifier userDataNotifier =
        Provider.of<UserDataNotifier>(context, listen: false);

    if (userDataNotifier.currentLoggedInUserData != null) {
      _currentLoggedInUserData = userDataNotifier.currentLoggedInUserData;
    } else {
      _currentLoggedInUserData = UserData(
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    UserDataNotifier userDataNotifier =
        Provider.of<UserDataNotifier>(context, listen: false);
    print('Logged in user id: ${_currentLoggedInUserData.id}');
    _saveUserData() async {
      if (!_formKey.currentState.validate()) {
        return;
      }
      _formKey.currentState.save();
      userDataNotifier.createOrUpdateUserData(_currentLoggedInUserData, true);
      Navigator.pop(context);
    }

    return Scaffold(
      appBar: AppBar(
        title: Text('Edit Profile'),
        actions: <Widget>[
          FlatButton(
              onPressed: () => _saveUserData(),
              child: Icon(
                FontAwesomeIcons.save,
                color: kThemeStyleButtonFillColour,
              )),
        ],
      ),
      body: ModalProgressHUD(
        inAsyncCall: showSpinner,
        child: SingleChildScrollView(
//          padding: EdgeInsets.only(top: 20.0),
          child: Form(
            autovalidateMode: AutovalidateMode.always,
            key: _formKey,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                LabelTextPadding(text: 'Business Information'),

                //business name
                RegularTextPadding(regText: 'Business Name'),
                _buildBusinessName(),
                SizedBox(height: 20.0),

                //business type
                RegularTextPadding(regText: 'Business Type'),
                Platform.isIOS
                    ? _buildCupertinoStyleBusinessType(context)
                    : _buildMaterialStyleBusinessType(context),

                //Trading currency
                RegularTextPadding(regText: 'Trading Currency'),
                Platform.isIOS
                    ? _buildCupertinoStyleTradingCurrency(context)
                    : _buildMaterialStyleTradingCurrency(context),

                //business location
                RegularTextPadding(regText: 'Location'),
                //address 1
                _buildAddress(),
                //city
                _buildCityField(),
                //postcode
                _buildPostcode(),
                //state
                _buildStateField(),
                //country
                Platform.isIOS
                    ? _buildCupertinoStyleCountry(context)
                    : _buildMaterialStyleCountry(context),

                SizedBox(
                  height: 20.0,
                ),
                DividerClass(),
                SizedBox(
                  height: 20.0,
                ),

                //Personal information
                LabelTextPadding(
                  text: 'Personal Information',
                ),
                _buildFirstNameField(),
                _buildLastNameField(),
                _buildPhoneNumberField(),
                // _buildEmailField(),

                //cancel and save buttons
                Padding(
                  padding: const EdgeInsets.fromLTRB(15.0, 10.0, 15.0, 10.0),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: <Widget>[
                      Buttons(
                          onPressedButton: () {
                            Navigator.pop(context);
                          },
                          buttonLabel: 'Cancel',
                          buttonColour: kThemeStyleButtonFillColour,
                          buttonTextStyle: kThemeStyleButton),
                      SizedBox(
                        width: 15.0,
                      ),
                      Buttons(
                          onPressedButton: () => _saveUserData(),
                          buttonLabel: 'Save',
                          buttonColour: kThemeStyleButtonFillColour,
                          buttonTextStyle: kThemeStyleButton),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  //business information
  Widget _buildBusinessName() {
    return Container(
      padding: EdgeInsets.all(20.0),
      child: TextFormField(
        initialValue: _currentLoggedInUserData.businessName,
        textAlign: TextAlign.left,
        onSaved: (value) {
          _currentLoggedInUserData.businessName = value;
        },
        validator: TextInputFieldValidator.validate,
        decoration:
            kTextFieldDecoration.copyWith(hintText: 'update business Name'),
      ),
    );
  }

  //business type - cupertino and material styles
  _buildCupertinoStyleBusinessType(BuildContext context) {
    return GestureDetector(
      child: Container(
        decoration: BoxDecoration(
            borderRadius: BorderRadius.all(Radius.circular(5.0)),
            border: Border.all(
              color: kThemeStyleButtonFillColour,
              width: 1,
            )),
        padding: const EdgeInsets.fromLTRB(10.0, 12.0, 10.0, 12.0),
        margin: EdgeInsets.all(20.0),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(selectedBusinessTypeDropDownValue),
            Icon(
              FontAwesomeIcons.caretDown,
              color: kThemeStyleButtonFillColour,
            ),
          ],
        ),
      ),
      onTap: () => showModalBottomSheet(
        context: context,
        builder: (BuildContext builder) {
          return Container(
            color: Colors.white,
            height: MediaQuery.of(context).copyWith().size.height / 4,
            child: CupertinoPicker(
              magnification: 1.5,
              children: List<Widget>.generate(businessType.length, (int index) {
                return Center(
                  child: Text(
                    businessType[index].toString(),
                    softWrap: true,
                    style: TextStyle(fontSize: 15.0),
                  ),
                );
              }),
              itemExtent: 25,
              onSelectedItemChanged: (index) {
                setState(() {
                  selectedBusinessTypeDropDownValue = businessType[index];
                });
              },
            ),
          );
        },
      ),
    );
  }

  _buildMaterialStyleBusinessType(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(5.0),
          border: Border.all(
            color: kThemeStyleButtonFillColour,
            width: 1,
          )),
      margin: EdgeInsets.all(20.0),
      width: MediaQuery.of(context).size.width,
      child: Center(
        child: DropdownButton(
          value: _currentLoggedInUserData.businessType == null
              ? selectedBusinessTypeDropDownValue
              : _currentLoggedInUserData.businessType,
          elevation: 15,
          iconDisabledColor: kThemeStyleButtonFillColour,
          iconEnabledColor: kThemeStyleButtonFillColour,
          underline: Container(),
          items: businessType
              .map(
                (businessType) => DropdownMenuItem(
                    value: businessType, child: Text(businessType)),
              )
              .toList(),
          onChanged: (newValue) {
            setState(() {
              selectedBusinessTypeDropDownValue = newValue;
              _currentLoggedInUserData.businessType = newValue;
            });
          },
        ),
      ),
    );
  }

  //trading currency - cupertino and material styles
  _buildCupertinoStyleTradingCurrency(BuildContext context) {
    return GestureDetector(
      onTap: () => showModalBottomSheet(
        context: context,
        builder: (BuildContext builder) {
          return Container(
            color: Colors.white,
            height: MediaQuery.of(context).copyWith().size.height / 4,
            child: CupertinoPicker(
              magnification: 1.5,
              children:
                  List<Widget>.generate(tradingCurrency.length, (int index) {
                return Center(
                  child: Text(
                    tradingCurrency[index].toString(),
                    softWrap: true,
                    style: TextStyle(fontSize: 15.0),
                  ),
                );
              }),
              itemExtent: 25,
              onSelectedItemChanged: (index) {
                setState(() {
                  selectedCurrencyDropDownValue = tradingCurrency[index];
                });
              },
            ),
          );
        },
      ),
      child: Container(
        decoration: BoxDecoration(
            borderRadius: BorderRadius.all(Radius.circular(0.5)),
            border: Border.all(
              color: kThemeStyleButtonFillColour,
              width: 1,
            )),
        padding: const EdgeInsets.fromLTRB(10.0, 12.0, 10.0, 12.0),
        margin: EdgeInsets.all(20.0),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(selectedCurrencyDropDownValue),
            Icon(
              FontAwesomeIcons.caretDown,
              color: kThemeStyleButtonFillColour,
            ),
          ],
        ),
      ),
    );
  }

  _buildMaterialStyleTradingCurrency(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(5.0),
          border: Border.all(
            color: kThemeStyleButtonFillColour,
            width: 1,
          )),
      margin: EdgeInsets.all(20.0),
      width: MediaQuery.of(context).size.width,
      child: Center(
        child: DropdownButton(
          value: _currentLoggedInUserData.businessType == null
              ? selectedCurrencyDropDownValue
              : _currentLoggedInUserData.businessTradingCurrency,
          icon: Icon(
            FontAwesomeIcons.caretDown,
            color: kThemeStyleButtonFillColour,
          ),
          elevation: 15,
          underline: Container(
            color: kThemeStyleButtonFillColour,
          ),
          items: tradingCurrency
              .map(
                (tradingCurrency) => DropdownMenuItem(
                    value: tradingCurrency, child: Text(tradingCurrency)),
              )
              .toList(),
          onChanged: (newValue) {
            setState(() {
              selectedCurrencyDropDownValue = newValue;
              _currentLoggedInUserData.businessTradingCurrency = newValue;
            });
          },
        ),
      ),
    );
  }

  //address field
  _buildAddress() {
    return Container(
      padding: EdgeInsets.all(20.0),
      child: TextFormField(
        initialValue: _currentLoggedInUserData.streetAddress,
        textAlign: TextAlign.left,
        onSaved: (value) {
          _currentLoggedInUserData.streetAddress = value;
        },
        validator: TextInputFieldValidator.validate,
        decoration:
            kTextFieldDecoration.copyWith(hintText: 'house and street address'),
      ),
    );
  }

  //city field
  _buildCityField() {
    return Container(
      padding: EdgeInsets.all(20.0),
      child: TextFormField(
        initialValue: _currentLoggedInUserData.city,
        textAlign: TextAlign.left,
        onSaved: (value) {
          _currentLoggedInUserData.city = value;
        },
        validator: TextInputFieldValidator.validate,
        decoration: kTextFieldDecoration.copyWith(hintText: 'enter city'),
      ),
    );
  }

  //postcode field
  _buildPostcode() {
    return Container(
      padding: EdgeInsets.all(20.0),
      child: TextFormField(
        initialValue: _currentLoggedInUserData.postcode,
        textAlign: TextAlign.left,
        onSaved: (value) {
          _currentLoggedInUserData.postcode = value;
        },
        validator: TextInputFieldValidator.validate,
        decoration: kTextFieldDecoration.copyWith(hintText: 'enter postcode'),
      ),
    );
  }

  //state field
  _buildStateField() {
    return Container(
      padding: EdgeInsets.all(20.0),
      child: TextFormField(
        initialValue: _currentLoggedInUserData.state,
        textAlign: TextAlign.left,
        onSaved: (value) {
          _currentLoggedInUserData.state = value;
        },
        validator: TextInputFieldValidator.validate,
        decoration: kTextFieldDecoration.copyWith(hintText: 'enter state'),
      ),
    );
  }

  //country field - cupertino and material styles
  _buildCupertinoStyleCountry(BuildContext context) {
    return GestureDetector(
      onTap: () => showModalBottomSheet(
        context: context,
        builder: (BuildContext builder) {
          return Container(
            color: Colors.white,
            height: MediaQuery.of(context).copyWith().size.height / 4,
            child: CupertinoPicker(
              magnification: 1.5,
              children: List<Widget>.generate(country.length, (int index) {
                return Center(
                  child: Text(
                    country[index].toString(),
                    softWrap: true,
                    style: TextStyle(fontSize: 15.0),
                  ),
                );
              }),
              itemExtent: 25,
              onSelectedItemChanged: (index) {
                setState(() {
                  selectedCountryDropDownValue = country[index];
                });
              },
            ),
          );
        },
      ),
      child: Container(
        decoration: BoxDecoration(
          borderRadius: BorderRadius.all(Radius.circular(0.5)),
          border: Border.all(
            color: kThemeStyleButtonFillColour,
            width: 1,
          ),
        ),
        padding: const EdgeInsets.fromLTRB(10.0, 12.0, 20.0, 12.0),
        margin: EdgeInsets.all(20.0),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(selectedCountryDropDownValue),
            Icon(
              FontAwesomeIcons.caretDown,
              color: kThemeStyleButtonFillColour,
            ),
          ],
        ),
      ),
    );
  }

  _buildMaterialStyleCountry(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(5.0),
        border: Border.all(
          color: kThemeStyleButtonFillColour,
          width: 1,
        ),
      ),
      margin: EdgeInsets.all(20.0),
      width: MediaQuery.of(context).size.width,
      child: Center(
        child: DropdownButton(
          value: _currentLoggedInUserData.country == null
              ? selectedCountryDropDownValue
              : _currentLoggedInUserData.country,
          elevation: 15,
          iconDisabledColor: kThemeStyleButtonFillColour,
          iconEnabledColor: kThemeStyleButtonFillColour,
          underline: Container(),
          items: country
              .map(
                (country) =>
                    DropdownMenuItem(value: country, child: Text(country)),
              )
              .toList(),
          onChanged: (newValue) {
            setState(() {
              selectedCountryDropDownValue = newValue;
              _currentLoggedInUserData.country = newValue;
            });
          },
        ),
      ),
    );
  }

  //logged in user personal info build
  //first name
  _buildFirstNameField() {
    return Container(
      padding: EdgeInsets.all(20.0),
      child: TextFormField(
        initialValue: _currentLoggedInUserData.firstName,
        textAlign: TextAlign.left,
        onSaved: (value) {
          _currentLoggedInUserData.firstName = value;
        },
        validator: TextInputFieldValidator.validate,
        decoration: kTextFieldDecoration.copyWith(hintText: 'your first Name'),
      ),
    );
  }

  //last name
  _buildLastNameField() {
    return Container(
      padding: EdgeInsets.all(20.0),
      child: TextFormField(
        initialValue: _currentLoggedInUserData.lastName,
        textAlign: TextAlign.left,
        onSaved: (value) {
          _currentLoggedInUserData.lastName = value;
        },
        validator: TextInputFieldValidator.validate,
        decoration: kTextFieldDecoration.copyWith(hintText: 'your last name'),
      ),
    );
  }

  //phone number
  _buildPhoneNumberField() {
    return Container(
      padding: EdgeInsets.all(20.0),
      child: TextFormField(
        initialValue: _currentLoggedInUserData.phoneNumber,
        textAlign: TextAlign.left,
        onSaved: (value) {
          _currentLoggedInUserData.phoneNumber = value;
        },
        validator: TextInputFieldValidator.validate,
        decoration:
            kTextFieldDecoration.copyWith(hintText: 'your phone number'),
      ),
    );
  }
}

class TextInputFieldValidator {
  static String validate(String value) {
    if (value.isEmpty) {
      return 'This field can\'t be empty, you must enter a text';
    }
    if (value.length < 3) {
      return 'You must enter at least a word';
    }
    return value;
  }
}
class ProfileFormScreen扩展了StatefulWidget{
静态常量字符串id='profile_form';
@凌驾
_ProfileFormScreenState createState()=>\u ProfileFormScreenState();
}
类_ProfileFormScreenState扩展状态{
最终的GlobalKey _formKey=GlobalKey();
UserData _currentLoggedInUserData;
bool showSpinner=false;
//全球宣言
字符串selectedBusinessTypeDropDownValue='Fashion';
字符串selectedCurrencyDropDownValue='AUD:Australian Dollar';
字符串selectedCountryDropDownValue='Australia';
字符串电子邮件;
@凌驾
void initState(){
super.initState();
UserDataNotifier UserDataNotifier=
Provider.of(上下文,listen:false);
if(userDataNotifier.currentLoggedInUserData!=null){
_currentLoggedInUserData=userDataNotifier.currentLoggedInUserData;
}否则{
_currentLoggedInUserData=用户数据(
无效的
无效的
无效的
无效的
无效的
无效的
无效的
无效的
无效的
无效的
无效的
无效的
无效的
无效的
无效的
);
}
}
@凌驾
小部件构建(构建上下文){
UserDataNotifier UserDataNotifier=
Provider.of(上下文,listen:false);
打印('登录用户id:${u currentLoggedInUserData.id}');
_saveUserData()异步{
如果(!\u formKey.currentState.validate()){
返回;
}
_formKey.currentState.save();
createOrUpdateUserData(_currentLoggedInUserData,true);
Navigator.pop(上下文);
}
返回脚手架(
appBar:appBar(
标题:文本(“编辑配置文件”),
行动:[
扁平按钮(
onPressed:()=>\u saveUserData(),
子:图标(
FontAwesomeIcons.save,
颜色:KThemestyleButtonFillColor,
)),
],
),
正文:ModalProgressHUD(
inAsyncCall:showSpinner,
子:SingleChildScrollView(
//填充:仅限边缘设置(顶部:20.0),
孩子:表格(
autovalidateMode:autovalidateMode.always,
键:_formKey,
子:列(
mainAxisAlignment:mainAxisAlignment.spaceBetween,
crossAxisAlignment:crossAxisAlignment.start,
C