微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

TextField 和 DatePicker 提供空值

如何解决TextField 和 DatePicker 提供空值

我正在尝试制作一个 todoApp,在我的添加屏幕中有一个用于任务标题的文本字段和一个用于任务日期的 DatePicker。我认为代码中一切正常,因为没有任何错误,但是当我单击“添加”按钮时,它会创建一个带有空标题和空日期的 TaskTile。我调试了代码,似乎我在 Provider 中使用 Add Button 提供的值是空的。就像我输入的内容删除,我在日期选择器中选择的内容删除。这是我的 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),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,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,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

工作代码(我正在创建一个带有简单 StreamController 的简单 UI 来演示):

// 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),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']}'),);
                },)),);
  }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。