I'm trying to build a simple Calculator with flutter. The prototype I've created isn't able the update the Screen, when using a setState and tryParse. I want to show the number a user presses instantly on the screen and when pressing another number, all the numbers get converted into one chain using tryPars.(....join()) (1 3 7 = 137). However, my first try isn't working (Code in num_pad.dart
). What did I do wrong?
landing_page.dart
import 'package:flutter/material.dart';
import 'package:flutter/src/foundation/key.dart';
import 'package:flutter/src/widgets/framework.dart';
import '../responsive_layout.dart';
import 'Widgets/build_column.dart';
class LandingPage extends StatefulWidget {
const LandingPage({Key? key}) : super(key: key);
@override
State<LandingPage> createState() => _LandingPageState();
}
class _LandingPageState extends State<LandingPage> {
@override
Widget build(BuildContext context) {
SizeConfig().init(context);
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue[800],
title: const Text(
"Calculator",
style: TextStyle(color: Colors.white, fontWeight: FontWeight.w500),
),
),
body: const BuildColumn(),
);
}
}
build_column.dart
import 'package:flutter/material.dart';
import '../../responsive_layout.dart';
import 'num_pad.dart';
List<double> firstInput = [];
int? outputNumber = 0;
class BuildColumn extends StatefulWidget {
const BuildColumn({
Key? key,
}) : super(key: key);
@override
State<BuildColumn> createState() => _BuildColumnState();
}
class _BuildColumnState extends State<BuildColumn> {
@override
Widget build(BuildContext context) {
return Column(children: [
Container(
width: SizeConfig.screenWidth,
height: SizeConfig.screenHeight / 3,
decoration: const BoxDecoration(color: Colors.white),
child: Align(
alignment: Alignment.topRight,
child: Padding(
padding: EdgeInsets.all(15.0),
child: Text(
"$outputNumber",
style: TextStyle(fontSize: 28),
),
),
),
),
Align(
alignment: Alignment.bottomRight,
child: Container(
width: SizeConfig.screenWidth * 0.85,
decoration: const BoxDecoration(
color: Colors.white,
border: Border(top: BorderSide(width: 2, color: Colors.grey)),
),
),
),
Expanded(
child: Padding(
padding: EdgeInsets.only(top: SizeConfig.blockSizeHorizontal * 5),
child: Container(
color: Colors.white,
child: NumPadBuild(),
),
),
)
]);
}
}
num_pad.dart
import 'package:flutter/material.dart';
import 'package:flutter_application_1/ui/Widgets/build_column.dart';
class NumPadBuild extends StatefulWidget {
const NumPadBuild({
Key? key,
}) : super(key: key);
@override
State<NumPadBuild> createState() => _NumPadBuildState();
}
class _NumPadBuildState extends State<NumPadBuild> {
@override
Widget build(BuildContext context) {
return Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Expanded(
child: Column(mainAxisAlignment: MainAxisAlignment.end, children: [
numPadButton("C", const Color.fromARGB(136, 0, 0, 0),
const Color.fromARGB(255, 39, 36, 36), 0),
numPadButton("7", const Color.fromARGB(136, 0, 0, 0),
const Color.fromARGB(255, 88, 85, 85), 7),
numPadButton("4", const Color.fromARGB(136, 0, 0, 0),
const Color.fromARGB(255, 88, 85, 85), 4),
numPadButton("1", const Color.fromARGB(136, 0, 0, 0),
const Color.fromARGB(255, 88, 85, 85), 1),
numPadButton("0", const Color.fromARGB(136, 0, 0, 0),
const Color.fromARGB(255, 88, 85, 85), 0),
]),
),
Expanded(
child: Column(mainAxisAlignment: MainAxisAlignment.end, children: [
numPadButton("±", const Color.fromARGB(137, 34, 33, 33),
const Color.fromARGB(255, 39, 36, 36), 0),
numPadButton("8", const Color.fromARGB(136, 0, 0, 0),
const Color.fromARGB(255, 88, 85, 85), 8),
numPadButton("5", const Color.fromARGB(136, 0, 0, 0),
const Color.fromARGB(255, 88, 85, 85), 5),
numPadButton("2", const Color.fromARGB(136, 0, 0, 0),
const Color.fromARGB(255, 88, 85, 85), 2),
numPadButton("√", const Color.fromARGB(136, 0, 0, 0),
Color.fromARGB(255, 88, 85, 85), 2)
]),
),
Expanded(
child: Column(mainAxisAlignment: MainAxisAlignment.end, children: [
numPadButton("%", const Color.fromARGB(137, 34, 33, 33),
const Color.fromARGB(255, 39, 36, 36), 0),
numPadButton("9", const Color.fromARGB(137, 34, 33, 33),
const Color.fromARGB(255, 88, 85, 85), 9),
numPadButton("6", const Color.fromARGB(137, 34, 33, 33),
const Color.fromARGB(255, 88, 85, 85), 6),
numPadButton("3", const Color.fromARGB(137, 34, 33, 33),
const Color.fromARGB(255, 88, 85, 85), 3),
numPadButton(",", const Color.fromARGB(136, 0, 0, 0),
const Color.fromARGB(255, 88, 85, 85), 0),
]),
),
Expanded(
child: Column(mainAxisAlignment: MainAxisAlignment.end, children: [
numPadButton("÷", const Color.fromARGB(137, 34, 33, 33),
const Color.fromARGB(255, 235, 141, 1), 0),
numPadButton("x", const Color.fromARGB(137, 34, 33, 33),
const Color.fromARGB(255, 235, 141, 1), 0),
numPadButton("-", const Color.fromARGB(137, 34, 33, 33),
const Color.fromARGB(255, 235, 141, 1), 0),
numPadButton(" ", const Color.fromARGB(137, 34, 33, 33),
const Color.fromARGB(255, 235, 141, 1), 0),
numPadButton("=", const Color.fromARGB(137, 34, 33, 33),
const Color.fromARGB(255, 235, 141, 1), 0)
]),
),
]);
}
Container numPadButton(String buttonName, Color buttonColorBorder,
Color buttonColor, double numPadValue) {
return Container(
decoration: BoxDecoration(
color: buttonColor,
border: Border.all(color: buttonColorBorder.withOpacity(0.5))),
child: Center(
child: TextButton(
onPressed: () {
setState(() {
firstInput.add(numPadValue);
outputNumber = int.tryParse(firstInput.join());
});
},
child: Text(
buttonName,
style: const TextStyle(color: Colors.white, fontSize: 25),
),
),
));
}
}
CodePudding user response:
The issue is you like to update BuildColumn
UI, but you are calling setState
inside NumPadBuild
. It will be good to start state-management like riverpod/bloc, For now you can use callback method for small cases like this. And avoid using global variables.
class NumPadBuild extends StatefulWidget {
final Function(double tappedNumber) callback;
const NumPadBuild({
required this.callback,
Key? key,
}) : super(key: key);
@override
State<NumPadBuild> createState() => _NumPadBuildState();
}
And on button
child: TextButton(
onPressed: () {
widget.callback(numPadValue);
},
child: Text(
buttonName,
style: const TextStyle(color: Colors.white, fontSize: 25),
),
The BuildColumn
state will update from this callback.
class _BuildColumnState extends State<BuildColumn> {
List<double> firstInput = [];
int? outputNumber = 0;
//......
child: NumPadBuild(
callback: (numPadValue) {
firstInput.add(numPadValue);
outputNumber = int.tryParse(firstInput.join());
setState(() {});
},
),
class BuildColumn extends StatefulWidget {
const BuildColumn({
Key? key,
}) : super(key: key);
@override
State<BuildColumn> createState() => _BuildColumnState();
}
class _BuildColumnState extends State<BuildColumn> {
List<double> firstInput = [];
int? outputNumber = 0;
@override
Widget build(BuildContext context) {
return Column(children: [
Container(
decoration: const BoxDecoration(color: Colors.white),
child: Align(
alignment: Alignment.topRight,
child: Padding(
padding: EdgeInsets.all(15.0),
child: Text(
"$outputNumber",
style: TextStyle(fontSize: 28),
),
),
),
),
Align(
alignment: Alignment.bottomRight,
child: Container(
width: 333,
decoration: const BoxDecoration(
color: Colors.white,
border: Border(top: BorderSide(width: 2, color: Colors.grey)),
),
),
),
Expanded(
child: Padding(
padding: EdgeInsets.zero,
child: Container(
color: Colors.white,
child: NumPadBuild(
callback: (numPadValue) {
firstInput.add(numPadValue);
outputNumber = int.tryParse(firstInput.join());
setState(() {});
},
),
),
),
)
]);
}
}
class NumPadBuild extends StatefulWidget {
final Function(double tappedNumber) callback;
const NumPadBuild({
required this.callback,
Key? key,
}) : super(key: key);
@override
State<NumPadBuild> createState() => _NumPadBuildState();
}
class _NumPadBuildState extends State<NumPadBuild> {
@override
Widget build(BuildContext context) {
return Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Expanded(
child: Column(mainAxisAlignment: MainAxisAlignment.end, children: [
numPadButton("C", const Color.fromARGB(136, 0, 0, 0),
const Color.fromARGB(255, 39, 36, 36), 0),
numPadButton("7", const Color.fromARGB(136, 0, 0, 0),
const Color.fromARGB(255, 88, 85, 85), 7),
numPadButton("4", const Color.fromARGB(136, 0, 0, 0),
const Color.fromARGB(255, 88, 85, 85), 4),
numPadButton("1", const Color.fromARGB(136, 0, 0, 0),
const Color.fromARGB(255, 88, 85, 85), 1),
numPadButton("0", const Color.fromARGB(136, 0, 0, 0),
const Color.fromARGB(255, 88, 85, 85), 0),
]),
),
Expanded(
child: Column(mainAxisAlignment: MainAxisAlignment.end, children: [
numPadButton("±", const Color.fromARGB(137, 34, 33, 33),
const Color.fromARGB(255, 39, 36, 36), 0),
numPadButton("8", const Color.fromARGB(136, 0, 0, 0),
const Color.fromARGB(255, 88, 85, 85), 8),
numPadButton("5", const Color.fromARGB(136, 0, 0, 0),
const Color.fromARGB(255, 88, 85, 85), 5),
numPadButton("2", const Color.fromARGB(136, 0, 0, 0),
const Color.fromARGB(255, 88, 85, 85), 2),
numPadButton("√", const Color.fromARGB(136, 0, 0, 0),
Color.fromARGB(255, 88, 85, 85), 2)
]),
),
Expanded(
child: Column(mainAxisAlignment: MainAxisAlignment.end, children: [
numPadButton("%", const Color.fromARGB(137, 34, 33, 33),
const Color.fromARGB(255, 39, 36, 36), 0),
numPadButton("9", const Color.fromARGB(137, 34, 33, 33),
const Color.fromARGB(255, 88, 85, 85), 9),
numPadButton("6", const Color.fromARGB(137, 34, 33, 33),
const Color.fromARGB(255, 88, 85, 85), 6),
numPadButton("3", const Color.fromARGB(137, 34, 33, 33),
const Color.fromARGB(255, 88, 85, 85), 3),
numPadButton(",", const Color.fromARGB(136, 0, 0, 0),
const Color.fromARGB(255, 88, 85, 85), 0),
]),
),
Expanded(
child: Column(mainAxisAlignment: MainAxisAlignment.end, children: [
numPadButton("÷", const Color.fromARGB(137, 34, 33, 33),
const Color.fromARGB(255, 235, 141, 1), 0),
numPadButton("x", const Color.fromARGB(137, 34, 33, 33),
const Color.fromARGB(255, 235, 141, 1), 0),
numPadButton("-", const Color.fromARGB(137, 34, 33, 33),
const Color.fromARGB(255, 235, 141, 1), 0),
numPadButton(" ", const Color.fromARGB(137, 34, 33, 33),
const Color.fromARGB(255, 235, 141, 1), 0),
numPadButton("=", const Color.fromARGB(137, 34, 33, 33),
const Color.fromARGB(255, 235, 141, 1), 0)
]),
),
]);
}
Container numPadButton(String buttonName, Color buttonColorBorder,
Color buttonColor, double numPadValue) {
return Container(
decoration: BoxDecoration(
color: buttonColor,
border: Border.all(color: buttonColorBorder.withOpacity(0.5))),
child: Center(
child: TextButton(
onPressed: () {
widget.callback(numPadValue);
},
child: Text(
buttonName,
style: const TextStyle(color: Colors.white, fontSize: 25),
),
),
));
}
}