我有一个表单,为了决定代码的可重用性,我决定将其分成多个小部件。我遇到的问题我不知道如何与每个组件进行交互。例如,如果主窗体声明了一个变量,我如何在存储在不同dart文件中的自定义文本字段小部件中访问该变量。
下面是我的代码
表单dart文件(main.dart)
import 'package:flutter/material.dart';
import 'package:finsec/widget/row_text_input.dart';
import 'package:finsec/widget/text_form_field.dart';
import 'package:finsec/widget/save_button.dart';
import 'package:finsec/utils/strings.dart';
import 'package:finsec/utils/dimens.dart';
import 'package:finsec/utils/colors.dart';
import 'package:finsec/widget/column_text_input.dart';
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Simple Interest Calculator App',
home: ThirdFragment(),
theme: ThemeData(
brightness: Brightness.dark,
primaryColor: Colors.indigo,
accentColor: Colors.indigoAccent),
));
}
class ThirdFragment extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _ThirdFragmentState();
}
}
class _ThirdFragmentState extends State<ThirdFragment> {
var _formKey = GlobalKey<FormState>();
var _currentItemSelected = '';
bool isError = false;
bool isButtonPressed = false;
@override
void initState() {
super.initState();
}
TextEditingController amountController = TextEditingController();
TextEditingController frequencyController = TextEditingController();
@override
Widget build(BuildContext context) {
TextStyle textStyle = Theme.of(context).textTheme.title;
return Scaffold(
appBar: AppBar(
title: Text('Simple Interest Calculator'),
),
body: Form(
key: _formKey,
child: SingleChildScrollView(
child: Column (children: [
Padding(
padding: EdgeInsets.only(top: 10.0, bottom: 5.0, left: 15.0, right: 15.0),
child: CustomTextField(textInputType:TextInputType.number,
textController: amountController,
errorMessage:'Enter Income Amount',
labelText:'Income Amount for testing'),
),
RowTextInput(inputName: 'Frequency:',
textInputType: TextInputType.number,
textController: frequencyController,
errorMessage: 'Choose Income Frequency',
labelText: 'Income Amount for testing'
),
RowTextInput(inputName: 'Date Paid:',
textInputType: TextInputType.number,
textController: datePaidController,
errorMessage: 'Pick Income Payment Date',
labelText: 'Income Amount for testing'
),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
MaterialButton(
height: margin_40dp,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(margin_5dp)),
minWidth: (MediaQuery.of(context).size.width * .9) / 2,
color: Theme.of(context).primaryColor,
textColor: white,
child: new Text(save),
onPressed: () => {
setState(() {
if (_formKey.currentState.validate()) {
// amountController.text.isEmpty ? amountController.text='Value require' : amountController.text='';
//this.displayResult = _calculateTotalReturns();
}
})
},
splashColor: blueGrey,
),
MaterialButton(
height: margin_40dp,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(margin_5dp)),
minWidth: (MediaQuery.of(context).size.width * .9) / 2,
color: Theme.of(context).primaryColor,
textColor: white,
child: new Text(save_and_continue),
onPressed: () => {},
splashColor: blueGrey,
)
])
]
),
),
}
RowTextInput是另一个包含此代码的dart文件。 RowTextInput.dart
import 'package:flutter/material.dart';
import 'package:finsec/utils/hex_color.dart';
class CustomTextField extends StatelessWidget {
CustomTextField({
this.textInputType,
this.textController ,
this.errorMessage,
this.labelText,
});
TextInputType textInputType;
TextEditingController textController;
String errorMessage, labelText;
@override
Widget build(BuildContext context) {
bool isError = false;
return Container(
child: TextFormField(
keyboardType: textInputType,
style: Theme
.of(context)
.textTheme
.title,
controller: textController,
validator: (String value) {
if (value.isEmpty) {
return errorMessage;
}
},
decoration: InputDecoration(
labelStyle: TextStyle(
color: Colors.grey,
fontSize: 16.0
),
contentPadding: EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 10.0), //size of textfield
errorStyle: TextStyle(
color: Colors.red,
fontSize: 15.0
),
border: OutlineInputBorder(
borderSide: BorderSide(width:5.0),
borderRadius: BorderRadius.circular(5.0)
)
)
),
);
}
}
我想从RowTextInput.dart访问位于main.dart中的isError和isButtonPressed变量,并能够分配值。然后main.dart应该能够看到在RowTextInput.dart文件中分配的那些值。
另外,我想将MaterialButton按钮移动到其自己的窗口小部件文件(button.dart)中,但随后我不知道当单击按钮或检查isError和值时,此dart文件将如何与main.dart文件进行交互。按下IS按钮。基本上,我将表单分为不同的组件(文本字段和按钮),并将它们存储在自己的单独文件中。但我希望所有文件main.dart,rowintputtext,button.dart(new)都能看到main.dart中变量的值并更改值。这可能吗?有没有更简单的方法?
预先感谢
答案 0 :(得分:2)
我还希望将表单分为多个类。这是我做的:
表格
在表单级别传递onSaved
函数。
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_CustomFormField(
onSaved: (value) => _myModelForm.field1 = value),
),
_CustomFormField2(
onSaved: (value) => _myModelForm.field2 = value),
)
),
RaisedButton(
onPressed: () {
// Validate will return true if the form is valid, or false if
// the form is invalid.
if (_formKey.currentState.validate()) {
// Process data.
_formKey.currentState.save();
// Observe if your model form is updated
print(myModelForm.field1);
print(myModelForm.field2)
}
},
child: Text('Submit'),
),
],
),
);
}
_CustomFormField1
onSaved
函数将作为参数传递。此类可以位于与表单相同的文件中,也可以位于另一个专用文件中。
class _CustomFormField1 extends StatelessWidget {
final FormFieldSetter<String> onSaved;
//maybe other properties...
_CustomFormField1({
@required this.onSaved,
});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 10.0),
child: TextFormField(
// You can keep your validator here
validator: (value) {
if (value.isEmpty) {
return 'Please enter some text';
}
return null;
},
onSaved: onSaved,
),
);
}
}
像onSaved
一样,如果需要,您可以对focusNode
,onFieldSubmitted
,validator
进行同样的操作
我希望它将对您和其他人有帮助
答案 1 :(得分:0)
考虑一下。在Flutter中,Button和RawMaterialButton已经在其他文件中。并能够完全按照您的意愿进行操作。
您应该创建一个文件mycustomButtons.dart。
在文件中,您应该创建一个将构建Buttons的类。
但是必须在其构造函数actionSave
actionSaveAndContinue
中有两个参数。
然后您将在您的主要对象中创建两个功能,例如:
void _save() {
setState(() {
if (_formKey.currentState.validate()) {
// amountController.text.isEmpty ? amountController.text='Value require' : amountController.text='';
//this.displayResult = _calculateTotalReturns();
}
})
}
然后,您应该将创建的函数作为参数传递:
MyCustomButtons(actionSave: _save, actionSaveAndContinue: _saveAndContinue)
因此,该按钮将具有所有需要的信息来更新main.dart变量。
textField几乎相同。但是您将需要通过验证功能和TextEditingController
。
您可以查看RawnMaterialButton
,TextFormField
的字体,以了解它们如何接收(并将)数据从一类传递到另一类。
答案 2 :(得分:0)
也许有一种更优雅的方式来做到这一点,但我目前正在尝试Singletons。请参见下面的代码:
<p>123</p> the result willl be ok I mean only 123
检查我如何在AppModel类的更新函数中使用这三个控制器。