我想做一个todoApp,在我的添加屏幕有一个文本字段的任务的标题和一个日期picker的任务的日期。我认为一切都是ok的代码,因为没有任何错误,但当我点击添加按钮,它创建一个TaskTile与空标题和空日期。我调试了代码,似乎我在添加按钮的提供程序中提供的值是空的。就像我输入的内容被删除了,我在日期选择器中选择的内容被删除了。这是我的AddScreen的代码。
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'task_data.dart';
import 'package:flutter/cupertino.dart';
import 'package:intl/intl.dart';
class AddTaskScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
String newTaskTitle;
DateTime _chosenDateTime;
DateFormat dateFormat = DateFormat("yyyy-MM-dd HH:mm:ss");
String formatedDate;
void _showDatePicker(ctx) {
showCupertinoModalPopup(
context: ctx,
builder: (_) => Container(
height: 500,
color: Color.fromARGB(255, 255, 255, 255),
child: Column(
children: [
Container(
height: 400,
child: CupertinoDatePicker(
initialDateTime: DateTime.now(),
onDateTimeChanged: (val) {
// setState(() {
// _chosenDateTime = val;
// });
_chosenDateTime = val;
formatedDate = dateFormat.format(_chosenDateTime);
// print('this is the selected date $formatedDate');
// print(_chosenDateTime);
}),
),
// Close the modal
CupertinoButton(
child: Text('OK'),
onPressed: () => Navigator.of(ctx).pop(),
)
],
),
));
}
return Container(
color: Color(0xff000014),
child: Container(
padding: EdgeInsets.all(20.0),
decoration: BoxDecoration(
color: Color(0xFF282D3A),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0),
topRight: Radius.circular(20.0),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(
'Add Task',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 30.0,
color: Colors.purple.shade400,
),
),
TextField(
decoration: InputDecoration(
border: InputBorder.none,
),
style: TextStyle(color: Colors.white),
autofocus: true,
textAlign: TextAlign.center,
onChanged: (newText) {
newTaskTitle = newText;
},
),
Container(
child: CupertinoButton(
padding: EdgeInsetsDirectional.zero,
child: Text('Select a date'),
onPressed: () => _showDatePicker(context),
),
),
FlatButton(
child: Text(
'Add',
style: TextStyle(
color: Colors.white,
),
),
color: Colors.purple.shade400,
onPressed: () {
//print('newtasktile is $newTaskTitle et formateddate is $formatedDate');// here the two //values are null when printed
Provider.of<TaskData>(context,listen: false )
.addTask(newTaskTitle, formatedDate);
Navigator.pop(context);
},
),
],
),
),
);
}
}
如果你有什么建议,请告诉我。谢谢。首先,为了方便地使用TextField
的值,应该使用TextEditingController
。要在选择日期时间后获得值,您可以从Dialog
方法返回一个值,然后将该值发送给Stream
工作代码(我正在创建一个简单的UI与简单的StreamController
来演示):
// TaskData class
class TaskData {
final StreamController _controller =
StreamController<Map<String, dynamic>>();
Stream<Map<String, dynamic>> get taskStream => _controller.stream;
addTask(String title, String date) {
_controller.add({'title': title, 'date': date});
}
}
// AddTask screen
class AddTaskScreen extends StatefulWidget {
@override
_AddTaskScreenState createState() => _AddTaskScreenState();
}
class _AddTaskScreenState extends State<AddTaskScreen> {
final _textController = TextEditingController();
DateFormat dateFormat = DateFormat("yyyy-MM-dd HH:mm:ss");
String chosenDate;
Future<String> _showDatePicker(ctx) async {
var formatedDate = DateTime.now();
return showCupertinoModalPopup(
context: ctx,
builder: (_) => Container(
height: 500,
color: Color.fromARGB(255, 255, 255, 255),
child: Column(
children: [
Container(
height: 400,
child: CupertinoDatePicker(
initialDateTime: DateTime.now(),
onDateTimeChanged: (val) {
formatedDate = val;
}),
),
// Close the modal
CupertinoButton(
child: Text('OK'),
// Return the formatted date here
onPressed: () => Navigator.of(ctx)
.pop(dateFormat.format(formatedDate)),
)
],
),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
// ... other lines
child: Column(
// ... other lines
TextField(
// Use the _textController here
controller: _textController,
decoration: InputDecoration(
border: InputBorder.none,
),
style: TextStyle(color: Colors.white),
autofocus: true,
textAlign: TextAlign.center,
),
Container(
child: CupertinoButton(
padding: EdgeInsetsDirectional.zero,
child: Text('Select a date'),
onPressed: () async {
// Wait for the return value
chosenDate = await _showDatePicker(context);
},
),
),
FlatButton(
child: Text(
'Add',
style: TextStyle(
color: Colors.white,
),
),
color: Colors.purple.shade400,
onPressed: () {
Provider.of<TaskData>(context, listen: false)
.addTask(_textController.text, chosenDate);
Navigator.pop(context);
},
),
],
),
),
),
);
}
}
// Main UI Screen
class SomeScreen extends StatefulWidget {
@override
_SomeScreenState createState() => _SomeScreenState();
}
class _SomeScreenState extends State<SomeScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FlatButton(
onPressed: () async {
await showDialog(
context: context,
builder: (context) => AddTaskScreen());
setState(() {});
},
child: Text('Add Task')),
Container(
child: StreamBuilder<Map<String, dynamic>>(
initialData: {},
stream: Provider.of<TaskData>(context).taskStream,
builder: (context, snapshot) {
if (!snapshot.hasData) return Container();
return Column(
children: [
Text(
'${snapshot.data['title']} | ${snapshot.data['date']}'),
],
);
},
)),
],
),
),
),
);
}
}