flutter - Setstate is not working in my calculator app in flutter
问题描述
I am new to flutter development and recently started my first working app : "The Calculator". But, I think, my setstate
is not working. Here's the code. Please help.
ignore_for_file: avoid_types_as_parameter_names, non_constant_identifier_names, prefer_const_constructors, prefer_const_literals_to_create_immutables
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
String init = '0';
var res = '';
var operationToPerform = '0';
var firstNum = 0;
var secondNum = 0;
_Calc(var got) {
if (got == 'AC') {
init = '0';
res = '0';
firstNum = 0;
operationToPerform = '0';
secondNum = 0;
} else if (got == 'C') {
firstNum = 0;
secondNum = 0;
} else if (got == '+' ||
got == '-' ||
got == '/' ||
got == '*' ||
got == '%') {
firstNum = int.parse(init);
res = '';
operationToPerform = got;
} else if (got == '=') {
secondNum = int.parse(init);
if (operationToPerform == '+') {
res = (firstNum + secondNum).toString();
}
if (operationToPerform == '-') {
res = (firstNum - secondNum).toString();
}
if (operationToPerform == '*') {
res = (firstNum * secondNum).toString();
}
if (operationToPerform == '/') {
res = (firstNum / secondNum).toString();
}
if (operationToPerform == '%') {
res = ((firstNum / secondNum) * 100).toString();
}
} else {
res = int.parse(init + got).toString();
}
setState(() {
init = res;
});
}
Widget Numbutton(var num, [var color = Colors.black, var text]) {
return Container(
decoration: BoxDecoration(boxShadow: [
BoxShadow(
color: Colors.grey.shade900,
offset: Offset(2, 2),
blurRadius: 15,
spreadRadius: 1,
),
BoxShadow(
color: Colors.grey.shade700,
offset: Offset(2, 2),
blurRadius: 15,
spreadRadius: 1,
)
], shape: BoxShape.circle),
child: ElevatedButton(
onPressed: () {
_Calc(num);
},
child: Text(
num,
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.w300,
color: text,
),
),
style: ElevatedButton.styleFrom(
shape: CircleBorder(), primary: color, fixedSize: Size(40, 40)),
),
);
}
Widget OpButton(var text) {
return ElevatedButton(
onPressed: () {
_Calc(text);
},
child: Text(
text,
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w400),
),
style: ElevatedButton.styleFrom(
primary: Colors.grey.shade900,
),
);
}
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.black,
body: Wrap(
direction: Axis.horizontal,
alignment: WrapAlignment.spaceEvenly,
children: <Widget>[
Column(
children: <Widget>[
SizedBox(
height: 220,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
init,
style: TextStyle(
color: Colors.grey.shade500,
),
)
],
),
SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Text(
init,
style:
TextStyle(color: Colors.grey.shade400, fontSize: 50),
),
],
),
SizedBox(
height: 50,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
OpButton('AC'),
OpButton('C'),
Numbutton('<', Colors.grey.shade300, Colors.grey.shade900),
Numbutton('%', Colors.grey.shade300, Colors.grey.shade900),
],
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Numbutton('7'),
Numbutton('8'),
Numbutton('9'),
Numbutton(
'*',
Colors.grey.shade300,
Colors.grey.shade900,
),
],
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Numbutton('4'),
Numbutton('5'),
Numbutton('6'),
Numbutton(
'+', Colors.grey.shade300, Colors.grey.shade900),
]),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Numbutton('1'),
Numbutton('2'),
Numbutton('3'),
Numbutton(
'-', Colors.grey.shade300, Colors.grey.shade900),
]),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Numbutton('00'),
Numbutton('0'),
Numbutton('.'),
Numbutton(
'/', Colors.grey.shade300, Colors.grey.shade900),
])
],
)
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_Calc('=');
},
child: Icon(Icons.arrow_forward_ios_rounded),
backgroundColor: Colors.grey.shade900,
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
),
);
}
}
I had tried doing that like init +=res;
The flutter version and dart version I am using is
Flutter 2.5.0 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 4cc385b4b8 (5 days ago) • 2021-09-07 23:01:49 -0700
Engine • revision f0826da7ef
Tools • Dart 2.14.0
I have tried restarting android studio and the android emulator, nothing seems to work.
解决方案
请将此初始化代码移出构建方法
String init = '0';
var res = '';
var operationToPerform = '0';
var firstNum = 0;
var secondNum = 0;
我已修改您的代码。请尝试一次
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String init = '0';
var res = '';
var operationToPerform = '0';
var firstNum = 0;
var secondNum = 0;
@override
Widget build(BuildContext context) {
_Calc(var got) {
if (got == 'AC') {
init = '0';
res = '0';
firstNum = 0;
operationToPerform = '0';
secondNum = 0;
} else if (got == 'C') {
firstNum = 0;
secondNum = 0;
} else if (got == '+' ||
got == '-' ||
got == '/' ||
got == '*' ||
got == '%') {
firstNum = int.parse(init);
res = '';
operationToPerform = got;
} else if (got == '=') {
secondNum = int.parse(init);
if (operationToPerform == '+') {
res = (firstNum + secondNum).toString();
}
if (operationToPerform == '-') {
res = (firstNum - secondNum).toString();
}
if (operationToPerform == '*') {
res = (firstNum * secondNum).toString();
}
if (operationToPerform == '/') {
res = (firstNum / secondNum).toString();
}
if (operationToPerform == '%') {
res = ((firstNum / secondNum) * 100).toString();
}
} else {
res = int.parse(init + got).toString();
}
setState(() {
init = res;
});
}
Widget Numbutton(var num, [var color = Colors.black, var text]) {
return Container(
decoration: BoxDecoration(boxShadow: [
BoxShadow(
color: Colors.grey.shade900,
offset: Offset(2, 2),
blurRadius: 15,
spreadRadius: 1,
),
BoxShadow(
color: Colors.grey.shade700,
offset: Offset(2, 2),
blurRadius: 15,
spreadRadius: 1,
)
], shape: BoxShape.circle),
child: ElevatedButton(
onPressed: () {
_Calc(num);
},
child: Text(
num,
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.w300,
color: text,
),
),
style: ElevatedButton.styleFrom(
shape: CircleBorder(), primary: color, fixedSize: Size(40, 40)),
),
);
}
Widget OpButton(var text) {
return ElevatedButton(
onPressed: () {
_Calc(text);
},
child: Text(
text,
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w400),
),
style: ElevatedButton.styleFrom(
primary: Colors.grey.shade900,
),
);
}
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.black,
body: Wrap(
direction: Axis.horizontal,
alignment: WrapAlignment.spaceEvenly,
children: <Widget>[
Column(
children: <Widget>[
SizedBox(
height: 220,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
init,
style: TextStyle(
color: Colors.grey.shade500,
),
)
],
),
SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Text(
init,
style:
TextStyle(color: Colors.grey.shade400, fontSize: 50),
),
],
),
SizedBox(
height: 50,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
OpButton('AC'),
OpButton('C'),
Numbutton('<', Colors.grey.shade300, Colors.grey.shade900),
Numbutton('%', Colors.grey.shade300, Colors.grey.shade900),
],
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Numbutton('7'),
Numbutton('8'),
Numbutton('9'),
Numbutton(
'*',
Colors.grey.shade300,
Colors.grey.shade900,
),
],
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Numbutton('4'),
Numbutton('5'),
Numbutton('6'),
Numbutton(
'+', Colors.grey.shade300, Colors.grey.shade900),
]),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Numbutton('1'),
Numbutton('2'),
Numbutton('3'),
Numbutton(
'-', Colors.grey.shade300, Colors.grey.shade900),
]),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Numbutton('00'),
Numbutton('0'),
Numbutton('.'),
Numbutton(
'/', Colors.grey.shade300, Colors.grey.shade900),
])
],
)
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_Calc('=');
},
child: Icon(Icons.arrow_forward_ios_rounded),
backgroundColor: Colors.grey.shade900,
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
),
);
}
}
推荐阅读
- python - Django Admin 模板覆盖
- angular - rxjs BehaviorSubject.next 未被触发
- jquery - 使用 jQuery Datatable 创建动态子标题的预期 json 数据格式应该如何?
- android - Android Wear - 如何为复杂功能 TYPE_RANGED_VALUE 绘制自定义 UI
- python - 如何消除数据中的急剧跳跃?
- java - 在 Arraylist 中设置初始容量不是一个好主意吗?
- ios - 致命异常:CALayerInvalidGeometry CALayer 边界包含 NaN:[-14 nan; 375 0]
- python - 如何在 Python 中将文本从 pdf 读入列表
- c - 是否保证解析为“(a?b:(c?d:e))”?
- jquery - Laravel 5.6 和 JQuery 不删除记录