gpt4 book ai didi

Flutter 提供者,在提供者中使用 GlobalKey 的正确方法

转载 作者:行者123 更新时间:2023-12-03 02:43:26 25 4
gpt4 key购买 nike

我是新来的 Provider package.并且只是为了学习目的制作演示应用程序。

这是我的简单 Form Widget 代码。

1) 注册页面 (我的应用程序在哪里启动)

class RegistrationPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text("Title"),
),
body: MultiProvider(providers: [
ChangeNotifierProvider<UserProfileProvider>.value(value: UserProfileProvider()),
ChangeNotifierProvider<RegiFormProvider>.value(value: RegiFormProvider()),
], child: AllRegistrationWidgets()),
);
}
}

class AllRegistrationWidgets extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
SetProfilePicWidget(),
RegistrationForm(),
],
),
),
),
BottomSaveButtonWidget()
],
),
),
);
}
}

class BottomSaveButtonWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final _userPicProvider =
Provider.of<UserProfileProvider>(context, listen: false);

final _formProvider =
Provider.of<RegiFormProvider>(context, listen: false);

return SafeArea(
bottom: true,
child: Container(
margin: EdgeInsets.all(15),
child: FloatingActionButton.extended(
heroTag: 'saveform',
icon: null,
label: Text('SUBMIT',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
)),
onPressed: () {
print(_userPicProvider.strImageFileName);
_formProvider.globalFormKey.currentState.validate();

print(_formProvider.firstName);
print(_formProvider.lastName);
},
)),
);
}
}

2) 报名表
class RegistrationForm extends StatefulWidget {
@override
_RegistrationFormState createState() => _RegistrationFormState();
}

class _RegistrationFormState extends State<RegistrationForm> {
TextEditingController _editingControllerFname;
TextEditingController _editingControllerLname;

@override
void initState() {
_editingControllerFname = TextEditingController();
_editingControllerLname = TextEditingController();

super.initState();
}

@override
Widget build(BuildContext context) {
final formProvider = Provider.of<RegiFormProvider>(context);
return _setupOtherWidget(formProvider);
}

_setupOtherWidget(RegiFormProvider _formProvider) {
return Container(
padding: EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
SizedBox(height: 20),
Text(
'Fields with (*) are required.',
style: TextStyle(fontStyle: FontStyle.italic),
textAlign: TextAlign.left,
),
SizedBox(height: 20),
_formSetup(_formProvider)
],
),
);
}

_formSetup(RegiFormProvider _formProvider) {
return Form(
key: _formProvider.globalFormKey,
child: Container(
child: Column(
children: <Widget>[
TextFormField(
controller: _editingControllerFname,
textCapitalization: TextCapitalization.sentences,
decoration: InputDecoration(
labelText: "First Name *",
hintText: "First Name *",
),
onSaved: (value) {},
validator: (String value) =>
_formProvider.validateFirstName(value)),
SizedBox(height: 15),
TextFormField(
controller: _editingControllerLname,
textCapitalization: TextCapitalization.sentences,
validator: (String value) =>
_formProvider.validateLastName(value),
onSaved: (value) {},
decoration: InputDecoration(
labelText: "Last Name *",
hintText: "Last Name *",
),
)
],
),
),
);
}

@override
void dispose() {
_editingControllerFname.dispose();
_editingControllerLname.dispose();
super.dispose();
}
}

3) RegiFormProvider
class RegiFormProvider with ChangeNotifier {

final GlobalKey<FormState> globalFormKey = GlobalKey<FormState>();

String _strFirstName;
String _strLasttName;

String get firstName => _strFirstName;
String get lastName => _strLasttName;

String validateFirstName(String value) {
if (value.trim().length == 0)
return 'Please enter first name';
else {
_strFirstName = value;
return null;
}
}

String validateLastName(String value) {
if (value.trim().length == 0)
return 'Please enter last name';
else {
_strLasttName = value;
return null;
}
}

}

在这里你可以看到, RegiFormProvider是我的第一个页面,其中其他是小部件树中的子小部件。我正在使用 final GlobalKey<FormState> globalFormKey = GlobalKey<FormState>();RegiFormProvider provider,因为我想在第一个 RegistrationPage 访问这个检查我的名字和姓氏是否有效。

最佳答案

我正在使用构建器小部件来获取如下所示的表单级上下文,然后我们可以通过使用该上下文轻松获取表单实例。这样我们就不再需要全局 key 了。

Form(
child: Builder(
builder: (ctx) {
return ListView(
padding: EdgeInsets.all(12),
children: <Widget>[
TextFormField(
decoration: InputDecoration(labelText: "Title"),
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) => FocusScope.of(context).nextFocus(),
initialValue: formProduct.title,
validator: validateTitle,
onSaved: (value) {
formProduct.title = value;
},
),
TextFormField(
decoration: InputDecoration(labelText: "Price"),
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) => FocusScope.of(context).nextFocus(),
initialValue: formProduct.price == null
? ""
: formProduct.price.toString(),
keyboardType: TextInputType.number,
validator: validatePrice,
onSaved: (value) {
formProduct.price = double.parse(value);
},
),
TextFormField(
decoration: InputDecoration(labelText: "Description"),
textInputAction: TextInputAction.next,
initialValue: formProduct.description,
maxLines: 3,
validator: validateDescription,
onFieldSubmitted: (_) => FocusScope.of(context).nextFocus(),
onSaved: (value) {
formProduct.description = value;
},
),
TextFormField(
decoration: InputDecoration(labelText: "Image Url"),
textInputAction: TextInputAction.done,
onFieldSubmitted: (_) => FocusScope.of(context).unfocus(),
initialValue: formProduct.imageUrl,
validator: validateImageUrl,
onSaved: (value) {
formProduct.imageUrl = value;
},
),
Padding(
padding: EdgeInsets.all(10),
child: FlatButton(
color: Colors.amberAccent,
onPressed: () {
if (Form.of(ctx).validate()) {
Form.of(ctx).save();
formProduct.id =
Random.secure().nextDouble().toString();
ProductsProvider provider =
Provider.of<ProductsProvider>(context,
listen: false);
editing
? provider.setProduct(formProduct)
: provider.addProduct(formProduct);
Router.back(context);
}
},
child: Text("Save"),
),
)
],
);
},
),
)

您可以看到 Form.of(ctx)给了我们当前的关卡形式。

关于Flutter 提供者,在提供者中使用 GlobalKey<FormState> 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56948352/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com