Flutter中if-else逻辑异常求助:输入分支计算未按预期执行
问题分析与修复
原代码核心问题
- 按钮点击时重复调用
_validateUserInput六次,每次仅传入单个输入,导致逻辑重复执行且无法正确判断输入组合状态 - 输入判断逻辑错误:直接将
TextEditingController对象与0比较,属于对象和数值的无效比较,永远无法触发正确分支 - 未处理输入为空或格式错误的情况,直接调用
double.parse会抛出异常 - 第二个分支未判断前四个输入为空的前提,不符合“前四个为空时才执行后两个分支”的需求逻辑
else分支的setState内return无意义,未正确处理无输入的情况
修复后的完整代码
import 'package:extended_math/extended_math.dart'; import 'package:flutter/material.dart'; class Calculation extends StatefulWidget { @override State<StatefulWidget> createState() { return _CalculationState(); } } class _CalculationState extends State<Calculation> { double Rzl = 0; // Real ZL double Izl = 0; // Imaginary ZL double Rzo = 0; // Real Zo double Izo = 0; // Imaginary Zo double t1 = 0; double t2 = 0; Complex infoText = Complex(re: 0, im: 0); final TextEditingController controller1 = TextEditingController(text: ''); final TextEditingController controller2 = TextEditingController(text: ''); final TextEditingController controller3 = TextEditingController(text: ''); final TextEditingController controller4 = TextEditingController(text: ''); final TextEditingController controller5 = TextEditingController(text: ''); final TextEditingController controller6 = TextEditingController(text: ''); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Calculator'), centerTitle: true, ), body: SingleChildScrollView( child: Padding( padding: const EdgeInsets.only(left: 20.0, right: 20.0), child: Column( children: [ Row( children: [ Expanded( child: SizedBox( height: 100, child: Padding( padding: const EdgeInsets.only(right: 10.0, top: 30.0), child: TextField( controller: controller1, decoration: InputDecoration( labelText: "Real ZL (ohms)", border: OutlineInputBorder( borderRadius: BorderRadius.circular(20), ), ), keyboardType: TextInputType.number, ), ), ), ), Expanded( child: SizedBox( height: 100, child: Padding( padding: const EdgeInsets.only(left: 10.0, top: 30.0), child: TextField( controller: controller2, decoration: InputDecoration( labelText: "Imaginary ZL (johms)", border: OutlineInputBorder( borderRadius: BorderRadius.circular(20), ), ), keyboardType: TextInputType.number, ), ), ), ), ], ), Row( children: [ Expanded( child: SizedBox( height: 100, child: Padding( padding: const EdgeInsets.only(right: 10.0, top: 30.0), child: TextField( controller: controller3, decoration: InputDecoration( labelText: "Real Zo (ohms)", border: OutlineInputBorder( borderRadius: BorderRadius.circular(20), ), ), keyboardType: TextInputType.number, ), ), ), ), Expanded( child: SizedBox( height: 100, child: Padding( padding: const EdgeInsets.only(left: 10.0, top: 30.0), child: TextField( controller: controller4, decoration: InputDecoration( labelText: "Imaginary Zo (johms)", border: OutlineInputBorder( borderRadius: BorderRadius.circular(20), ), ), keyboardType: TextInputType.number, ), ), ), ), ], ), Row( children: [ Expanded( child: SizedBox( height: 100, child: Padding( padding: const EdgeInsets.only(right: 10.0, top: 30.0), child: TextField( controller: controller5, decoration: InputDecoration( labelText: "test1", border: OutlineInputBorder( borderRadius: BorderRadius.circular(20), ), ), keyboardType: TextInputType.number, ), ), ), ), Expanded( child: SizedBox( height: 100, child: Padding( padding: const EdgeInsets.only(left: 10.0, top: 30.0), child: TextField( controller: controller6, decoration: InputDecoration( labelText: "test2", border: OutlineInputBorder( borderRadius: BorderRadius.circular(20), ), ), keyboardType: TextInputType.number, ), ), ), ), ], ), const SizedBox(height: 25.0), ElevatedButton( onPressed: _validateUserInput, child: const Text('Reflection Coefficient'), ), const SizedBox(height: 25.0), Text("Result: $infoText", style: const TextStyle(color: Colors.red)), ], ), ), ), ); } void _validateUserInput() { // 辅助方法:判断输入是否为有效数字 bool isNumeric(String? s) { if (s == null || s.isEmpty) return false; return double.tryParse(s) != null; } // 前四个输入都有效 bool hasFirstFourInputs = isNumeric(controller1.text) && isNumeric(controller2.text) && isNumeric(controller3.text) && isNumeric(controller4.text); // 后两个输入有效,且前四个都为空 bool hasSecondTwoInputs = !isNumeric(controller1.text) && !isNumeric(controller2.text) && !isNumeric(controller3.text) && !isNumeric(controller4.text) && isNumeric(controller5.text) && isNumeric(controller6.text); setState(() { if (hasFirstFourInputs) { Rzl = double.parse(controller1.text); Izl = double.parse(controller2.text); Rzo = double.parse(controller3.text); Izo = double.parse(controller4.text); final zlvalue = Complex(re: Rzl, im: Izl); final zovalue = Complex(re: Rzo, im: Izo); final rcvalue = (zlvalue - zovalue) / (zlvalue + zovalue); infoText = rcvalue; } else if (hasSecondTwoInputs) { t1 = double.parse(controller5.text); t2 = double.parse(controller6.text); final rc1 = Complex(re: t1, im: t2); final rc2 = Complex(re: t1, im: t2); final rcvalue = rc1 + rc2; infoText = rcvalue; } else { // 所有输入为空或不符合条件时,清空结果 infoText = const Complex(re: 0, im: 0); } }); } }
关键修复点说明
- 按钮点击逻辑修正:将按钮的
onPressed改为直接调用_validateUserInput,确保一次性处理所有输入状态 - 输入有效性判断:新增
isNumeric辅助方法,判断输入是否为有效数字,避免直接double.parse抛出异常 - 分支条件修正:
- 第一个分支:判断前四个输入均为有效数字才执行反射系数计算
- 第二个分支:明确判断前四个输入均无效,且后两个输入有效时才执行对应计算,符合需求逻辑
- 无输入情况处理:
else分支清空结果,避免残留旧数据 - 代码规范优化:类名改为首字母大写(符合Dart规范),添加
final修饰控制器,清理未使用的成员变量
内容的提问来源于stack exchange,提问作者maskrider69
相关产品推荐
相关产品推荐

