我以前发布过有关此问题的信息,但我仍然面临 它将数据从有状态小部件返回到无状态小部件
我正在使用的小部件是DateTimePickerFormField小部件,我将其用作有状态小部件中的子级
所以我看了https://flutter.io/docs/cookbook/navigation/returning-data#complete-example
用于从小部件返回数据。但是,返回数据的小部件是无状态小部件...在我的情况下不是
所以代码如下
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Add a Reminder'),
),
body:
new Container(
padding: new EdgeInsets.all(20.0),
child: new Form(
child: new ListView(
children: <Widget>[
new TextFormField(
keyboardType: TextInputType.text,
// Use email input type for emails.
decoration: new InputDecoration(
hintText: 'Title of reminder',
),
),
dateAndTimeWidget(context),
RaisedButton(
child: Text('Save'),
onPressed: () {
Navigator.pop(context);
},
)
],
),)
,
)
,
);
}
该小部件正在调用方法:dateAndTimeWidget,该方法应返回带状态的dateTime小部件并将结果数据保存在变量中:
dateAndTimeWidget(BuildContext context) async {
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context)=> dateTime()),
);
}
然后这是dateTime Statful小部件
class dateTime extends StatefulWidget{
@override
dateTimeState createState() => dateTimeState();
}
class dateTimeState extends State<dateTime>{
static DateTime dateT;
InputType inputType = InputType.both;
final formats = {
InputType.both: DateFormat("EEEE, MMMM d, yyyy 'at' h:mma"),
InputType.date: DateFormat('yyyy-MM-dd'),
InputType.time: DateFormat("HH:mm"),
};
Widget build(BuildContext context) => Container(
child: DateTimePickerFormField(
inputType: InputType.both,
editable: true,
format: formats[inputType],
decoration: InputDecoration(
labelText: 'Date/Time', hasFloatingPlaceholder: false),
onChanged: (dt) {
setState(() => dateT = dt);
Navigator.of(context).pop(dateT);
},
)
);
}
我还没有使用值结果 因为错误是我从没有进入添加提醒页面,并且说结果推送导航方法指向null
答案 0 :(得分:0)
在这种情况下,不适合使用Navigator传递数据。因为页面和您的dateTime
小部件之间没有页面过渡。我建议您实现ValueChanged
回调以在同一屏幕的小部件之间传递数据。
有点棘手。但是material.dart
的窗口小部件经常使用这种技术。我希望这能帮到您!
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
DateTime dateT;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Add a Reminder'),
),
body: new Container(
padding: new EdgeInsets.all(20.0),
child: new Form(
child: new ListView(
children: <Widget>[
new TextFormField(
keyboardType: TextInputType.text,
// Use email input type for emails.
decoration: new InputDecoration(
hintText: 'Title of reminder',
),
),
dateTime(
onDateTimeChanged: (newDateTime) {
dateT = newDateTime;
},
),
RaisedButton(
child: Text('Save'),
onPressed: () {
Navigator.pop(context);
},
)
],
),
),
),
);
}
}
class dateTime extends StatefulWidget {
final ValueChanged<DateTime> onDateTimeChanged;
dateTime({Key key, this.onDateTimeChanged}) : super(key: key);
@override
dateTimeState createState() => dateTimeState();
}
class dateTimeState extends State<dateTime> {
DateTime dateT;
InputType inputType = InputType.both;
final formats = {
InputType.both: DateFormat("EEEE, MMMM d, yyyy 'at' h:mma"),
InputType.date: DateFormat('yyyy-MM-dd'),
InputType.time: DateFormat("HH:mm"),
};
Widget build(BuildContext context) => Container(
child: DateTimePickerFormField(
inputType: InputType.both,
editable: true,
format: formats[inputType],
decoration: InputDecoration(
labelText: 'Date/Time', hasFloatingPlaceholder: false),
onChanged: (dt) {
widget.onDateTimeChanged(dt);
},
),
);
}
(顺便说一下,您的dateAndTimeWidget
是一种方法,不是小部件。因此,如果将其分配给Column的子级(列表),Flutter框架将无法理解。)
答案 1 :(得分:0)
要获得更多节省时间的解决方案,以从另一个小部件返回值并使用它,下面是Flutter Dropdown的示例:
import 'package:flutter/material.dart';
import 'package:paxi_ride/constant.dart';
class BuildDropdown extends StatefulWidget {
final ValueChanged<String> onChanged;
String defaultValue, selectedValue, dropdownHint;
List<String> itemsList;
BuildDropdown(
{Key key,
this.itemsList,
this.defaultValue,
this.dropdownHint,
this.onChanged})
: super(key: key);
@override
_BuildDropdownState createState() => _BuildDropdownState();
}
class _BuildDropdownState extends State<BuildDropdown> {
String _value;
@override
Widget build(BuildContext context) {
return Container(
// height: 40,
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 0),
margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
color: Colors.white,
child: DropdownButton<String>(
items: widget.itemsList.map(
(String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
},
).toList(),
value: _value == null ? widget.defaultValue : _value,
isExpanded: true,
onChanged: (String value) {
setState(() {
_value = value;
});
widget.onChanged(value);
},
hint: Text(widget.dropdownHint),
style: TextStyle(
fontSize: 14,
color: brownColorApp,
),
iconEnabledColor: brownColorApp,
iconSize: 14,
underline: Container(),
),
);
}
}
从另一个您想要在其中获得选定值的小部件中调用此小部件:
String selectedValue; //class field
BuildDropdown(
itemsList: ['Option 1','Option 2'],
defaultValue: 'Option 1',
dropdownHint: 'Select Required Option',
onChanged: (value) {
selectedValue = value;
},
),
在任何需要的地方使用此值,它将随着下拉选择的更改而改变。