首页 > 解决方案 > Flutter - 如何在条件下调用函数?

问题描述

我只是想在条件发生时调用一个函数,就像两件事变得相等 if (int.tryParse(data.oil)! >= int.parse(text1)) {function} 类似的事情,我的代码如下:

  ToastService? service;
  void stateOil() {
    service = new ToastService(
      appName: 'desktoasts',
      companyName: 'alexmercerind',
      productName: 'desktoasts_example',
    );

    if (int.tryParse(data.oil)! >= int.parse(text1) && data.oil != 'null') {
      setState(() {
        Toast toast = new Toast(
          type: ToastType.text02,
          title: 'Hello World!',
          subtitle: 'This toast contains a subtitle.',
        );
        service!.show(toast);
        toast.dispose();
      });
    }
  }

是什么data.oil?它是一个字符串,它的值每 900 毫秒更新一次。 text1是我从 TextField 收到的用户输入并将其保存在其中(在 FloatingActionButton 的 onPressed 属性中)

在此处完成 Home 小部件代码

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

class _HomeState extends State<Home> {
  // dialogBuilderBuilder() =>
  // void Function(String text) onSubmit

  static Route<Object> dialogBuilder(BuildContext context) {
    // final text = await Navigator.of(context).push(dialogBuilder());
    TextEditingController myController = TextEditingController();
    print(myController.text);
    return DialogRoute(
      context: context,
      builder: (BuildContext context) => AlertDialog(
        actions: [
          ElevatedButton(
              onPressed: () {
                Navigator.pop(context);
              },
              child: Text('Cancel')),
          ElevatedButton(
              onPressed: () {
                ScaffoldMessenger.of(context)
                  ..removeCurrentSnackBar()
                  ..showSnackBar(SnackBar(
                      content: Text(
                          'You will be notified when Oil Temp reaches ${myController.text} degrees.')));
                Navigator.of(context).pop(myController.text);
              },
              child: Text('Ok')),
        ],
        title: Text('Red line temp'),
        content: TextField(
          // onSubmitted: onSubmit,
          onChanged: (value) {},
          controller: myController,
          decoration:
              InputDecoration(hintText: "Enter the red line temperature"),
        ),
      ),
    );
  }

  late dynamic data;
  late dynamic data2;
  void stateData() async {
    ToastService? service;
    dynamic data1 = await ToolDataState.getData();
    dynamic data3 = await ToolDataIndicator.getData2();
    setState(() {
      data = data1;
      data2 = data3;
    });
  }

  String text1 = '1000';
  ToastService? service;
  void stateOil() {
    service = new ToastService(
      appName: 'desktoasts',
      companyName: 'alexmercerind',
      productName: 'desktoasts_example',
    );

    if (int.tryParse(data.oil)! >= int.parse(text1) && data.oil != 'null') {
      setState(() {
        Toast toast = new Toast(
          type: ToastType.text02,
          title: 'Hello World!',
          subtitle: 'This toast contains a subtitle.',
        );
        service!.show(toast);
        toast.dispose();
      });
    }
  }

  @override
  void initState() {
    super.initState();
    const oneSec = Duration(milliseconds: 900);
    Timer.periodic(oneSec, (Timer t) => stateData());
    WidgetsBinding.instance!.addPostFrameCallback((_) {
      data = ModalRoute.of(context)?.settings.arguments as ToolDataState;
      data2 = ModalRoute.of(context)?.settings.arguments as ToolDataIndicator;
    });
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Stack(fit: StackFit.expand, children: <Widget>[
        Center(child: CircularProgressIndicator()),
        Center(
          child: FadeInImage.memoryNetwork(
              placeholder: kTransparentImage,
              image:
                  'https://www.getdroidtips.com/wp-content/uploads/2020/06/war-thunder-featured.jpg'),
        ),
        ImageFiltered(
          imageFilter: ImageFilter.blur(sigmaX: 7.0, sigmaY: 7.0),
          child: Image.network(
            "https://www.getdroidtips.com/wp-content/uploads/2020/06/war-thunder-featured.jpg",
            height: MediaQuery.of(context).size.height,
            width: MediaQuery.of(context).size.width,
            fit: BoxFit.cover,
          ),
        ),
        Stack(
          children: [
            Scaffold(
              backgroundColor: Colors.transparent,
              resizeToAvoidBottomInset: true,
              appBar: AppBar(
                  backgroundColor: Colors.transparent,
                  centerTitle: true,
                  title: data2.name != 'NULL'
                      ? Text("You're flying ${data2.name}")
                      : Text("No vehicle data available / Not flying!")),
              body: Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    Flexible(
                      fit: FlexFit.loose,
                      child: Container(
                          height: 60,
                          decoration: BoxDecoration(
                              gradient: LinearGradient(
                                colors: [
                                  Color.fromRGBO(255, 143, 158, 0.5),
                                  Color.fromRGBO(255, 188, 143, 0.5),
                                ],
                                begin: Alignment.centerLeft,
                                end: Alignment.centerRight,
                              ),
                              borderRadius: const BorderRadius.all(
                                Radius.circular(20.0),
                              ),
                              boxShadow: [
                                BoxShadow(
                                  color: Colors.pink.withOpacity(0.2),
                                  spreadRadius: 4,
                                  blurRadius: 10,
                                  offset: Offset(0, 3),
                                )
                              ]),
                          child:
                              data2.throttle == 'nul' || data2.throttle == '0'
                                  ? TextButton.icon(
                                      icon: Icon(Icons.speed),
                                      onPressed: () {},
                                      label: Text(
                                        'Stationary/ Engine dead / No data!  ',
                                        style: TextStyle(
                                            fontSize: 27,
                                            letterSpacing: 2,
                                            color: Colors.black,
                                            fontWeight: FontWeight.bold),
                                      ),
                                    )
                                  : TextButton.icon(
                                      icon: Icon(Icons.speed),
                                      onPressed: () {},
                                      label: Text(
                                        'Throttle = ${(double.parse(data2.throttle) * 100).toStringAsFixed(0)}%',
                                        style: TextStyle(
                                            fontSize: 27,
                                            letterSpacing: 2,
                                            color: Colors.black,
                                            fontWeight: FontWeight.bold),
                                      ),
                                    )),
                    ),
                    Flexible(
                      fit: FlexFit.loose,
                      child: Container(
                          height: 60,
                          decoration: BoxDecoration(
                              gradient: LinearGradient(
                                colors: [
                                  Color.fromRGBO(255, 143, 158, 0.5),
                                  Color.fromRGBO(255, 188, 143, 0.5),
                                ],
                                begin: Alignment.centerLeft,
                                end: Alignment.centerRight,
                              ),
                              borderRadius: const BorderRadius.all(
                                Radius.circular(20.0),
                              ),
                              boxShadow: [
                                BoxShadow(
                                  color: Colors.pink.withOpacity(0.2),
                                  spreadRadius: 4,
                                  blurRadius: 10,
                                  offset: Offset(0, 3),
                                )
                              ]),
                          child: data.ias == 'null' || data.ias == '0'
                              ? TextButton.icon(
                                  icon: Icon(Icons.speed),
                                  onPressed: () {},
                                  label: Text(
                                    'Not Flying/ No data!  ',
                                    style: TextStyle(
                                        fontSize: 27,
                                        letterSpacing: 2,
                                        color: Colors.black,
                                        fontWeight: FontWeight.bold),
                                  ),
                                )
                              : TextButton.icon(
                                  icon: Icon(Icons.speed),
                                  onPressed: () {},
                                  label: Text(
                                    'IAS = ${data.ias!} km/h ',
                                    style: TextStyle(
                                        fontSize: 27,
                                        letterSpacing: 2,
                                        color: Colors.black,
                                        fontWeight: FontWeight.bold),
                                  ),
                                )),
                    ),
                    Flexible(
                      fit: FlexFit.loose,
                      child: Container(
                          height: 60,
                          decoration: BoxDecoration(
                              gradient: LinearGradient(
                                colors: [
                                  Color.fromRGBO(255, 143, 158, 0.5),
                                  Color.fromRGBO(255, 188, 143, 0.5),
                                ],
                                begin: Alignment.centerLeft,
                                end: Alignment.centerRight,
                              ),
                              borderRadius: const BorderRadius.all(
                                Radius.circular(20.0),
                              ),
                              boxShadow: [
                                BoxShadow(
                                  color: Colors.pink.withOpacity(0.2),
                                  spreadRadius: 4,
                                  blurRadius: 10,
                                  offset: Offset(0, 3),
                                )
                              ]),
                          child: data.tas == 'null' || data.tas == '0'
                              ? TextButton.icon(
                                  icon: Icon(Icons.speed),
                                  onPressed: () {},
                                  label: Text(
                                    'Not Flying/ No data!  ',
                                    style: TextStyle(
                                        fontSize: 27,
                                        letterSpacing: 2,
                                        color: Colors.black,
                                        fontWeight: FontWeight.bold),
                                  ),
                                )
                              : TextButton.icon(
                                  icon: Icon(Icons.speed),
                                  onPressed: () {},
                                  label: Text(
                                    'TAS = ${data.tas!} km/h ',
                                    style: TextStyle(
                                        fontSize: 27,
                                        letterSpacing: 2,
                                        color: Colors.black,
                                        fontWeight: FontWeight.bold),
                                  ),
                                )),
                    ),
                    Flexible(
                      fit: FlexFit.loose,
                      child: Container(
                          height: 60,
                          decoration: BoxDecoration(
                              gradient: LinearGradient(
                                colors: [
                                  Color.fromRGBO(255, 143, 158, 0.5),
                                  Color.fromRGBO(255, 188, 143, 0.5),
                                ],
                                begin: Alignment.centerLeft,
                                end: Alignment.centerRight,
                              ),
                              borderRadius: const BorderRadius.all(
                                Radius.circular(20.0),
                              ),
                              boxShadow: [
                                BoxShadow(
                                  color: Colors.red.withOpacity(0.2),
                                  spreadRadius: 4,
                                  blurRadius: 7,
                                  offset: Offset(0, 3),
                                )
                              ]),
                          child: data.oil == 'null' || data.oil == '15'
                              ? TextButton.icon(
                                  icon: Icon(Icons.airplanemode_active),
                                  label: AnimatedContainer(
                                    duration: Duration(seconds: 1),
                                    child: Text(
                                      'No data available!  ',
                                      style: TextStyle(
                                          fontSize: 27,
                                          letterSpacing: 2,
                                          color: Colors.black,
                                          fontWeight: FontWeight.bold),
                                    ),
                                  ),
                                  onPressed: () {},
                                )
                              : TextButton.icon(
                                  icon: Icon(Icons.airplanemode_active),
                                  label: AnimatedContainer(
                                    duration: Duration(seconds: 1),
                                    child: Text(
                                      'Oil Temp= ${data.oil} degrees',
                                      style: TextStyle(
                                          fontSize: 27,
                                          letterSpacing: 2,
                                          color: Colors.black,
                                          fontWeight: FontWeight.bold),
                                    ),
                                  ),
                                  onPressed: () {},
                                )),
                    ),
                    Flexible(
                      fit: FlexFit.loose,
                      child: Container(
                          height: 60,
                          decoration: BoxDecoration(
                              gradient: LinearGradient(
                                colors: [
                                  Color.fromRGBO(255, 143, 158, 0.5),
                                  Color.fromRGBO(255, 188, 143, 0.5),
                                ],
                                begin: Alignment.centerLeft,
                                end: Alignment.centerRight,
                              ),
                              borderRadius: const BorderRadius.all(
                                Radius.circular(20.0),
                              ),
                              boxShadow: [
                                BoxShadow(
                                  color: Colors.pink.withOpacity(0.2),
                                  spreadRadius: 4,
                                  blurRadius: 10,
                                  offset: Offset(0, 3),
                                )
                              ]),
                          child: data.water == 'null' || data.water == '15'
                              ? TextButton.icon(
                                  icon: Icon(Icons.water),
                                  onPressed: () {},
                                  label: Text(
                                    'Jet / No data available!!  ',
                                    style: TextStyle(
                                        fontSize: 27,
                                        letterSpacing: 2,
                                        color: Colors.black,
                                        fontWeight: FontWeight.bold),
                                  ),
                                )
                              : TextButton.icon(
                                  icon: Icon(Icons.water),
                                  onPressed: () {},
                                  label: Text(
                                    'Water Temp = ${data.water!} degrees  ',
                                    style: TextStyle(
                                        fontSize: 27,
                                        letterSpacing: 2,
                                        color: Colors.black,
                                        fontWeight: FontWeight.bold),
                                  ),
                                )),
                    ),
                  ],
                ),
              ),
              floatingActionButton: FloatingActionButton(
                  tooltip: 'Enter Oil temperature!',
                  child: Icon(Icons.warning_amber_outlined),
                  onPressed: () async {
                    Object? text = await Navigator.of(context)
                        .push(dialogBuilder(context));
                    print(text);
                    setState(() {
                      late Object? text1 = text;
                      print(text1);
                    });
                  }),
            ),
          ],
        ),
      ]),
    );
  }
}

我还有一个 dataReceiver.dart 文件,如下所示:

  String? ias;
  String? tas;
  String? oil;
  String? water;

  ToolData({this.ias, this.tas, this.oil, this.water});

  static Future<ToolData> getData() async {

    try {
      // make the request
      Response? response = await get(Uri.parse('http://localhost:8111/state'));
      Map<String,dynamic>? data = jsonDecode(response.body);
      //print(data);
      return ToolData(ias: data!['IAS, km/h'].toString(),tas: data['TAS, km/h'].toString(),oil: data['oil temp 1, C'].toString(), water: data['water temp 1, C'].toString());
    }
    catch (e, stackTrace) {
      log('Encountered error: $e', stackTrace:stackTrace);
      rethrow;
    }
  }

}

任何帮助表示赞赏(这是一个 Windows 应用程序

标签: flutter

解决方案


目前,您的代码存在两个问题:

  1. Bad state: Stream has been listened。”您面临的错误位于 ToastService 内部。如果您查看文档,您会看到它全局声明了 ToastService 并在main函数中对其进行了初始化:
ToastService? service;

void main() {
  service = new ToastService(
    appName: 'desktoasts',
    companyName: 'alexmercerind',
    productName: 'desktoasts_example',
  );
  runApp(MyApp());
}

这高度表明 ToastService 必须只初始化一次。但是,您每次调用时都会创建一个新的 ToastService stateOil,因此会出现错误。

要修复它,只需在函数内部初始化service 一次main然后再调用runApp. 每当您需要使用该服务时,只需参考此变量即可。

  1. 条件
if (int.tryParse(data.oil)! >= int.parse(text1) && data.oil != 'null') {

如果data.oil等于'null'int.tryParse(data.oil)就会返回null。由于 Dart 中的条件是从左到右计算的,并且您在!表达式之后使用 a ,它会引发“用于空值的空检查运算符”错误。

要修复它,只需翻转条件即可;或者

if (data.oil != 'null' && int.tryParse(data.oil)! >= int.parse(text1)) {

旁注:第一个片段的更好的空安全版本是

late final ToastService service;

void main() {
  service = ToastService(
    appName: 'desktoasts',
    companyName: 'alexmercerind',
    productName: 'desktoasts_example',
  );
  runApp(MyApp());
}

推荐阅读