flutter - 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 应用程序)
解决方案
目前,您的代码存在两个问题:
- “ 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
. 每当您需要使用该服务时,只需参考此变量即可。
- 条件
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());
}