【问题标题】:how to call a Function from another Dart file如何从另一个 Dart 文件中调用函数
【发布时间】:2022-02-06 21:06:57
【问题描述】:

我有这个函数来处理我的日期和时间选择器小部件......下面的代码......

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('...');
  }

最初它在我的添加新任务类/dart 文件“Stateful Widget”中,一切正常,但现在我想在按下按钮时在主屏幕上使用该功能。

然后我检查了how to call a function from another dart file 上的 StackOverflow 问题,该解决方案要求我将函数保存在不同的 dart 文件中,然后像这个示例一样从那里调用它

void launchWebView () {
  print("1234");
} 

当我这样做时,我得到了一个我查找的错误,这是因为我的函数中的“setState”所以我需要把它放在一个有状态的小部件中,

import 'package:flutter/material.dart';

class SelectDateAndTime extends StatefulWidget {
  @override
  _SelectDateAndTimeState createState() => _SelectDateAndTimeState();
}

class _SelectDateAndTimeState extends State<SelectDateAndTime> {

  DateTime? _selectedDate;
// DateTime _selectedDate;
  DateTime? selectedDateAndTime;

  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('...');
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    throw UnimplementedError();
  }
}

这是我的代码与我遵循的示例的唯一区别,当我尝试调用该函数时仍然出现错误,并且我已经检查了与另一个 dart 文件/类中的 clling 函数相关的所有问题,但没有其中有 SetState,所以他们的解决方案对我不起作用

这是我只调用函数名称时遇到的错误 贝娄是我尝试打电话时遇到的错误

onPressed: () => selectedDateAndTime!.selectDayAndTimeL(),

我应该从这里做什么?

【问题讨论】:

    标签: flutter dart flutter-layout dart-pub dart-null-safety


    【解决方案1】:

    我猜你最初有一个 Statefull 小部件,它可能看起来像这样:

    class OriginalWidget extends StatefulWidget {
      @override
      _OriginalWidgetState createState() => _OriginalWidgetState();
    }
    
    class _OriginalWidgetState extends State<OriginalWidget> {
    
      DateTime? _selectedDate;
      DateTime? selectedDateAndTime;
    
      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('...');
      }
    
      @override
      Widget build(BuildContext context) {
        return FlatButton(
              onPressed: () => selectDayAndTimeL(context));
      } 
    } 
    

    现在,您要做的是重用 selectDayAndTimeL 函数的逻辑。

    问题在于selectedDateAndTime 变量和setState 方法都特定于Statefull 小部件_OriginalWidgetState

    您需要做的是修改您的 selectDayAndTimeL 函数,以便它可以将那些特定于小部件的内容作为参数。

    所以,本质上你会做的是:

    首先将函数创建为独立函数,例如在新的 dart 文件中。确保从正文中删除特定于小部件的内容并将它们作为参数保留:

      Future selectDayAndTimeL(BuildContext context, void Function(DateTime) onDateAndTimeSelected) 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
        }
        
          onDateAndTimeSelected(DateTime(
            selectedDay!.year,
            selectedDay!.month,
            selectedDay!.day,
            selectedTime!.hour,
            selectedTime!.minute,
          ));
        // print('...');
      }
    

    第二,在您的新 Statefull 小部件上,您现在可以调用此函数,请确保发送新的 onDateAndTimeSelected 参数:

    class SecondWidget extends StatefulWidget {
      @override
      _SecondWidgetState createState() => _SecondWidgetState();
    }
    
    class _SecondWidgetState extends State<SecondWidget> {
      DateTime? selectedDateAndTime;
    
      @override
      Widget build(BuildContext context) {
        return FlatButton(
              onPressed: () => selectDayAndTimeL(context, 
            setState((DateTime selectedValue) {
                 selectedDateAndTime = selectedValue;
             } ) 
        ));
      }  
    } 
    

    然后您可以对需要调用您的函数的任何其他 Statefull 小部件遵循相同的逻辑。

    【讨论】:

    • 请问“日期时间?selectedDateAndTime;”来自哪里?我当时试图使用它,因为我试图将函数放在一个名为“SelectedDateAndTime”的有状态小部件中,就像你在第一个代码 sn-p 中提到的那样,但是因为我们正在取出有状态小部件并将函数作为独立的名称为selectedDateAndTimeL 的代码是否意味着我应该将DateTime? selectedDateAndTime; 替换为DateTime? selectedDateAndTimeL; ?...注意区别是其中一个以“L”结尾,而另一个不
    【解决方案2】:

    setState 告诉有状态小部件根据更改的数据重新渲染。在您的情况下,您正在更改 selectedDateAndTime 并使用更新的数据重新构建小部件。

    如果您想从“远程”函数更新/重建小部件,您需要使用回调。

    Future selectDayAndTimeL(BuildContext context,Function(DateTime time) onDateTimeSelected)  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
        }
        // call the callback here with your calculated data
        onDateTimeSelected(
          DateTime(
            selectedDay!.year,
            selectedDay!.month,
            selectedDay!.day,
            selectedTime!.hour,
            selectedTime!.minute,
          ),
        );
      }
    

    然后在你调用这个函数的StatefulWidget中:

    selectDayAndTimeL(BuildContext context,(time) {
      setState(() {
        selectedDateAndTime = time;
      });
    });
    

    【讨论】:

    • 我应该在onpressed上写这段代码吗? selectDayAndTimeL(BuildContext context,(time) { setState(() { selectedDateAndTime = time; }); });
    猜你喜欢
    • 2020-08-25
    • 2021-04-12
    • 1970-01-01
    • 1970-01-01
    • 2016-03-11
    • 1970-01-01
    • 2020-04-26
    • 2018-07-27
    相关资源
    最近更新 更多