如何在另一个飞镖文件上设置未来的构建器函数?

发布于 2025-02-04 00:17:54 字数 2393 浏览 4 评论 0原文

我有一个未来(异步)日期&时间选择器函数,该功能从我的状态小部件的正文内正常工作,其中包含“构建器”,并且可以通过以下方式通过以下方式调用该函数:

onPressed: () {SelectDayAndTimeL();}, 

代码:

Future _selectDayAndTimeL(BuildContext context) async {
    DateTime _selectedDay = await showDatePicker(
        context: context,
        initialDate: DateTime.now(),
        firstDate: DateTime(2021),
        lastDate: DateTime(2030),
        builder: (BuildContext context, Widget child) => child);

    TimeOfDay _selectedTime = await showTimePicker(
      context: context,
      initialTime: TimeOfDay.now(),
    );

    if (_selectedDay != null && _selectedTime != null) {
      //a little check
    }
    setState(() {
      selectedDateAndTime = DateTime(
        _selectedDay.year,
        _selectedDay.month,
        _selectedDay.day,
        _selectedTime.hour,
        _selectedTime.minute,
      );
      // _selectedDate = _selectedDay;
    });
    // print('...');
  }

现在我想能够能够要从不同的飞镖文件/屏幕调用此函数,这意味着我必须将此功能保留在我试图执行的其他飞镖文件上,但是由于功能中的setState在该功能中,因此需要在已有状态的小部件内。我尝试将其放入一个状态的小部件中,但一直遇到错误。

class Picker extends StatefulWidget {
  @override
  _PickerState createState() => _PickerState();
}

class _PickerState extends State<Picker> {
  @override
  Future<Widget> build(BuildContext context) async { //the error in on the build on this line
    DateTime _selectedDay = await showDatePicker(
        context: context,
        initialDate: DateTime.now(),
        firstDate: DateTime(2021),
        lastDate: DateTime(2030),
        builder: (BuildContext context, Widget child) => child);

    TimeOfDay _selectedTime = await showTimePicker(
      context: context,
      initialTime: TimeOfDay.now(),
    );

    if (_selectedDay != null && _selectedTime != null) {
      //a little check
    }
    setState(() {
      selectedDateAndTime = DateTime(
        _selectedDay.year,
        _selectedDay.month,
        _selectedDay.day,
        _selectedTime.hour,
        _selectedTime.minute,
      );
      // _selectedDate = _selectedDay;
    });
  }
}

我如何正确地将未来功能放置在一个状态的小部件中,以及如何将其命名为Onpressed?

我不知道我给出这个问题的标题是否真的是它应该是什么,但我不知道该怎么说。

I have a Future (async) Date&Time picker function which works fine from within the body of my stateful widget which contains the "Builder" and the function can be called via the onpressed by just this:

onPressed: () {SelectDayAndTimeL();}, 

Code:

Future _selectDayAndTimeL(BuildContext context) async {
    DateTime _selectedDay = await showDatePicker(
        context: context,
        initialDate: DateTime.now(),
        firstDate: DateTime(2021),
        lastDate: DateTime(2030),
        builder: (BuildContext context, Widget child) => child);

    TimeOfDay _selectedTime = await showTimePicker(
      context: context,
      initialTime: TimeOfDay.now(),
    );

    if (_selectedDay != null && _selectedTime != null) {
      //a little check
    }
    setState(() {
      selectedDateAndTime = DateTime(
        _selectedDay.year,
        _selectedDay.month,
        _selectedDay.day,
        _selectedTime.hour,
        _selectedTime.minute,
      );
      // _selectedDate = _selectedDay;
    });
    // print('...');
  }

Now I want to be able to call this function from different dart files/screens which means I have to keep this function on a different dart file which I have tried to do, but because of the setState in the function it needs to be inside a stateful widget. I have tried putting it inside a stateful widget but keeps getting errors.

class Picker extends StatefulWidget {
  @override
  _PickerState createState() => _PickerState();
}

class _PickerState extends State<Picker> {
  @override
  Future<Widget> build(BuildContext context) async { //the error in on the build on this line
    DateTime _selectedDay = await showDatePicker(
        context: context,
        initialDate: DateTime.now(),
        firstDate: DateTime(2021),
        lastDate: DateTime(2030),
        builder: (BuildContext context, Widget child) => child);

    TimeOfDay _selectedTime = await showTimePicker(
      context: context,
      initialTime: TimeOfDay.now(),
    );

    if (_selectedDay != null && _selectedTime != null) {
      //a little check
    }
    setState(() {
      selectedDateAndTime = DateTime(
        _selectedDay.year,
        _selectedDay.month,
        _selectedDay.day,
        _selectedTime.hour,
        _selectedTime.minute,
      );
      // _selectedDate = _selectedDay;
    });
  }
}

enter image description here

How do I properly place the Future Function inside a stateful widget and how to call it on an onpressed?

I don't know if the title I gave this question is actually what it's supposed to be, but I don't know how else to put it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我恋#小黄人 2025-02-11 00:17:54

方法中的整个setstate是问题。您的方法应该做一件事:从用户那里获得日期和时间。责任结束了。

Future<DateTime> SelectDayAndTimeL(BuildContext context) async {
    DateTime _selectedDay = await showDatePicker(
        context: context,
        initialDate: DateTime.now(),
        firstDate: DateTime(2021),
        lastDate: DateTime(2030),
        builder: (BuildContext context, Widget child) => child);

    TimeOfDay _selectedTime = await showTimePicker(
      context: context,
      initialTime: TimeOfDay.now(),
    );

    if (_selectedDay != null && _selectedTime != null) {
      //a little check
    }
    return DateTime(
        _selectedDay.year,
        _selectedDay.month,
        _selectedDay.day,
        _selectedTime.hour,
        _selectedTime.minute,
      );
  }

现在,您的按压力变为:

onPressed: () async { 
     final pickedDatetime = await SelectDayAndTimeL(context); 
     setState(() { selectedDateAndTime = pickedDatetime });
},

您已将代码成功分为选择事物和小部件的功能,该功能在选择事物后会更新。

现在可以在其他每个小部件中重复使用日期和时间的功能。

The whole setState inside your method is the problem. Your method should do one thing: get a date and time from the user. And there it's responsibility ends.

Future<DateTime> SelectDayAndTimeL(BuildContext context) async {
    DateTime _selectedDay = await showDatePicker(
        context: context,
        initialDate: DateTime.now(),
        firstDate: DateTime(2021),
        lastDate: DateTime(2030),
        builder: (BuildContext context, Widget child) => child);

    TimeOfDay _selectedTime = await showTimePicker(
      context: context,
      initialTime: TimeOfDay.now(),
    );

    if (_selectedDay != null && _selectedTime != null) {
      //a little check
    }
    return DateTime(
        _selectedDay.year,
        _selectedDay.month,
        _selectedDay.day,
        _selectedTime.hour,
        _selectedTime.minute,
      );
  }

Now your onPressed becomes:

onPressed: () async { 
     final pickedDatetime = await SelectDayAndTimeL(context); 
     setState(() { selectedDateAndTime = pickedDatetime });
},

You have sucessfully divided your code into the function that picks a thing and your widget, which updates after the thing is picked.

The function that picks the date and time can now be reused in every other widget.

冬天的雪花 2025-02-11 00:17:54

创建一个功能,该函数将DateTime作为状态小部件的参数和设置。在状态小部件中写下此。将此函数传递给其他类作为参数。选择日期后,通过选择DateTime选择的DateTime来调用此方法。

Create a function which will take datetime as a parameter and setstate of the stateful widget. Write this inside the stateful widget. Pass this function to the other class as an argument. Once the date is picked call this method by passing the datetime selected.

删除会话 2025-02-11 00:17:54

您应该将SetState函数本身作为参数传递给该方法。这样,在方法内部,您将始终使用正确的状态设置器函数。这是尤其需要的,因为您需要在小部件内保留变量_SELECTEDDAY等,而不是静态方法。尝试以下操作:

Future selectDayAndTimeL(BuildContext context, Function(DateTime) dateTimeSetter) async { //add a function to receive and use the
    DateTime _selectedDay = await showDatePicker(
        context: context,
        initialDate: DateTime.now(),
        firstDate: DateTime(2021),
        lastDate: DateTime(2030),
        builder: (BuildContext context, Widget child) => child);

    TimeOfDay _selectedTime = await showTimePicker(
      context: context,
      initialTime: TimeOfDay.now(),
    );

    if (_selectedDay != null && _selectedTime != null) {
      //a little check
    }
    // Create the variable with the picked date
    DateTime selectedDateAndTime = DateTime(
        _selectedDay.year,
        _selectedDay.month,
        _selectedDay.day,
        _selectedTime.hour,
        _selectedTime.minute,
      );
     //call the function from the parameter, which will be executed on the calling widget
    dateTimeSetter(selectedDateAndTime);
    ....
}

然后,调用您的函数以显示DateTime Picker传递上下文,以及接收DateTime参数的函数,该函数将是用户选择的参数。当用户选择日期时,将执行此功能主体,调用setState并设置采摘时间变量。

class Picker extends StatefulWidget {
  DateTime pickedTime;

  @override
  _PickerState createState() => _PickerState();
}

class _PickerState extends State<Picker> {
  @override
  Future<Widget> build(BuildContext context) async {
     return ...
         _selectDayAndTimeL(context, (DateTime time){
           setState((){
             widget.pickedTime = time;
           });
         });
     ...

您还可以将函数从参数提取到一个普通命名函数中,只需在参数中使用其名称,但是我将其保留为现在,以使其更简单。

另外,如果需要,请不要忘记将您的方法公开并静态。

You should pass the setState function itself as a parameter to the method. This way, inside the method you will always be using the correct state setter function. That is especially necessary since you need to keep the variables _selectedDay etc inside the widget, not on the static method. Try this:

Future selectDayAndTimeL(BuildContext context, Function(DateTime) dateTimeSetter) async { //add a function to receive and use the
    DateTime _selectedDay = await showDatePicker(
        context: context,
        initialDate: DateTime.now(),
        firstDate: DateTime(2021),
        lastDate: DateTime(2030),
        builder: (BuildContext context, Widget child) => child);

    TimeOfDay _selectedTime = await showTimePicker(
      context: context,
      initialTime: TimeOfDay.now(),
    );

    if (_selectedDay != null && _selectedTime != null) {
      //a little check
    }
    // Create the variable with the picked date
    DateTime selectedDateAndTime = DateTime(
        _selectedDay.year,
        _selectedDay.month,
        _selectedDay.day,
        _selectedTime.hour,
        _selectedTime.minute,
      );
     //call the function from the parameter, which will be executed on the calling widget
    dateTimeSetter(selectedDateAndTime);
    ....
}

Then, call your function to show the datetime picker passing the context, and a function that receives a DateTime parameter, which will be the parameter picked by the user. When the user picks a date, this function body will be executed, calling setState and setting the pickedTime variable.

class Picker extends StatefulWidget {
  DateTime pickedTime;

  @override
  _PickerState createState() => _PickerState();
}

class _PickerState extends State<Picker> {
  @override
  Future<Widget> build(BuildContext context) async {
     return ...
         _selectDayAndTimeL(context, (DateTime time){
           setState((){
             widget.pickedTime = time;
           });
         });
     ...

You can also extract the function from the parameter into a normal named function, and just use its name in the parameter, but I'll leave it as is for now to make it simpler.

Also, don't forget to make your method public and static if necessary for the scope of your code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文