Flutter SDK is an open-source software development kit for building beautiful UI which is natively compiled. In this article, we are going to create an advanced calculator app by using some advanced packages available in Flutter. In this app, you get some functionality. In this app you have only one screen in that screen we perform our whole calculator functionality - Addition, Subtract, Multiply and Divide.

Steps to Implement a Calculator Application
Step 1: Create a new Flutter Application
Create a new Flutter application using the command Prompt. To create a new app, write the following command and run it.
flutter create app_nameTo know more about it refer this article: Creating a Simple Application in Flutter
Step 2: Adding the Dependency
To add the dependency to the pubspec.yaml file, add math_expressions as a dependency in the dependencies part of the pubspec.yaml file, as shown below:
dependencies:
flutter:
sdk: flutter
math_expressions: ^2.6.0
Now, run the command below in the terminal.
flutter pub getStep 3: Import libraries
Now, import these packages in the main.dart file,
import 'package:flutter/material.dart';
import 'package:math_expressions/math_expressions.dart';
Step 4: Working with main.dart
Add the boilerplate code below in main.dart to create a basic structure with an AppBar and body using a Scaffold.
import 'package:flutter/material.dart';
import 'package:math_expressions/math_expressions.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData.dark(),
home: MyCalculator(),
debugShowCheckedModeBanner: false,
);
}
}
class MyCalculator extends StatefulWidget {
const MyCalculator({super.key});
@override
State<MyCalculator> createState() => _MyCalculatorState();
}
class _MyCalculatorState extends State<MyCalculator> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
],
),
);
}
}
Step 5: Initialize variables Code
Initialize required variables.
// Variables to hold numbers and operation strings
double num1 = 0.0;
double num2 = 0.0;
// Stores the user input
var input = '';
// Stores the calculation result
var output = '';
Step 4: Create methods
Develop methods to enable functionality for each button.
// Function to handle button clicks
_onButtonClicked(value) {
// If the user clicks "AC",
// clear input and output
if (value == "AC") {
input = '';
output = '';
}
// If the user clicks "A",
// delete the last character
else if (value == "A") {
if (input.isNotEmpty) {
input = input.substring(0, input.length - 1);
}
}
// If the user clicks "=",
// evaluate the expression
else if (value == "=") {
if (input.isNotEmpty) {
var userinput = input;
// Replace any characters if
// needed (currently does nothing)
userinput = input.replaceAll("", "");
// Use math_expressions package
// to parse the input expression
Parser p = Parser();
Expression expression = p.parse(userinput);
ContextModel cm = ContextModel();
var finalvalue = expression.evaluate(EvaluationType.REAL, cm);
// Convert the result to string
output = finalvalue.toString();
// Remove trailing ".0" if present
if (output.endsWith(".0")) {
output = output.substring(0, output.length - 2);
}
}
}
// Otherwise, add the pressed button's
// value to the input string
else {
input = input + value;
}
// Refresh the UI with new data
setState(() {});
}
Step 5: Develop UI
- Button
Below is the helper function to create a calculator button.
// Helper function to create a calculator button
button(text, color, tcolor) {
return Expanded(
// Expanded makes the button fill
// available horizontal space
child: Container(
// Padding around the button
padding: EdgeInsets.all(10),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
// Padding inside the button
padding: EdgeInsets.all(10),
// Button background color
backgroundColor: color,
shape: RoundedRectangleBorder(
// Rounded corners
borderRadius: BorderRadius.circular(5),
),
),
// Call _onButtonClicked with the
// button's text when pressed
onPressed: () => _onButtonClicked(text),
child: Text(
text,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
// Text color
color: tcolor,
),
),
),
),
);
}
- Alignment
Use the code below to align all types of buttons.
Column(
children: [
// Expanded widget to show the
// display area (input and output)
Expanded(
child: Container(
// Not necessary because Expanded sets height
height: 200,
width: double.infinity,
color: Colors.transparent,
// Column for showing the input and output texts
child: Column(
// Align text to the right
crossAxisAlignment: CrossAxisAlignment.end,
// Place texts at the bottom
mainAxisAlignment: MainAxisAlignment.end,
children: [
// Display user input
Text(
input,
style: TextStyle(fontSize: 48, color: Colors.white),
),
SizedBox(
height: 10,
),
// Display calculation output
Text(
output,
style: TextStyle(
fontSize: 30,
color: Colors.white.withOpacity(0.7),
),
),
SizedBox(
height: 20,
),
],
),
),
),
// First row of buttons: AC, A,
// (empty), and division operator
Row(
children: [
button("AC", Colors.black, Colors.orangeAccent),
button("A", Colors.black, Colors.orangeAccent),
button("", Colors.transparent, Colors.white),
button("/", Colors.black, Colors.orangeAccent),
],
),
// Second row of buttons: 7, 8, 9,
// and multiplication operator
Row(
children: [
button("7", Colors.black, Colors.white),
button("8", Colors.black, Colors.white),
button("9", Colors.black, Colors.white),
button("*", Colors.black, Colors.orangeAccent),
],
),
// Third row of buttons: 4, 5, 6,
// and subtraction operator
Row(
children: [
button("4", Colors.black, Colors.white),
button("5", Colors.black, Colors.white),
button("6", Colors.black, Colors.white),
button("-", Colors.black, Colors.orangeAccent),
],
),
// Fourth row of buttons: 1, 2, 3,
// and addition operator
Row(
children: [
button("1", Colors.black, Colors.white),
button("2", Colors.black, Colors.white),
button("3", Colors.black, Colors.white),
button("+", Colors.black, Colors.orangeAccent),
],
),
// Fifth row of buttons: %, 0, .,
// and equals operator
Row(
children: [
button("%", Colors.black, Colors.orangeAccent),
button("0", Colors.black, Colors.white),
button(".", Colors.black, Colors.white),
button("=", Colors.orangeAccent, Colors.white),
],
),
],
),
Complete Source Code
main.dart:
import 'package:flutter/material.dart';
import 'package:math_expressions/math_expressions.dart';
// Main function: Entry point of the app
void main() {
runApp(const MyApp());
}
// MyApp widget: The root of the application
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
// App title
title: 'Flutter Demo',
theme: ThemeData.dark(),
// Set MyCalculator as the home screen
home: MyCalculator(),
// Hide the debug banner
debugShowCheckedModeBanner: false,
);
}
}
// MyCalculator widget: A stateful
// widget for the calculator UI
class MyCalculator extends StatefulWidget {
const MyCalculator({super.key});
@override
State<MyCalculator> createState() => _MyCalculatorState();
}
// State class for MyCalculator widget
class _MyCalculatorState extends State<MyCalculator> {
// Variables to hold numbers and operation strings
double num1 = 0.0;
double num2 = 0.0;
// Stores the user input
var input = '';
// Stores the calculation result
var output = '';
// Function to handle button clicks
_onButtonClicked(value) {
// If the user clicks "AC", clear input and output
if (value == "AC") {
input = '';
output = '';
}
// If the user clicks "A", delete the last character
else if (value == "A") {
if (input.isNotEmpty) {
input = input.substring(0, input.length - 1);
}
}
// If the user clicks "=", evaluate the expression
else if (value == "=") {
if (input.isNotEmpty) {
var userinput = input;
// Replace any characters if needed
// (currently does nothing)
userinput = input.replaceAll("", "");
// Use math_expressions package to parse
// the input expression
Parser p = Parser();
Expression expression = p.parse(userinput);
ContextModel cm = ContextModel();
var finalvalue = expression.evaluate(EvaluationType.REAL, cm);
// Convert the result to string
output = finalvalue.toString();
// Remove trailing ".0" if present
if (output.endsWith(".0")) {
output = output.substring(0, output.length - 2);
}
}
}
// Otherwise, add the pressed button's
// value to the input string
else {
input = input + value;
}
// Refresh the UI with new data
setState(() {});
}
@override
Widget build(BuildContext context) {
return Scaffold(
// Scaffold provides the basic
// layout structure
body: Column(
children: [
// Expanded widget to show the
// display area (input and output)
Expanded(
child: Container(
// Not necessary because Expanded sets height
height: 200,
width: double.infinity,
color: Colors.transparent,
// Column for showing the input and output texts
child: Column(
// Align text to the right
crossAxisAlignment: CrossAxisAlignment.end,
// Place texts at the bottom
mainAxisAlignment: MainAxisAlignment.end,
children: [
// Display user input
Text(
input,
style: TextStyle(fontSize: 48, color: Colors.white),
),
SizedBox(
height: 10,
),
// Display calculation output
Text(
output,
style: TextStyle(
fontSize: 30,
color: Colors.white.withOpacity(0.7),
),
),
SizedBox(
height: 20,
),
],
),
),
),
// First row of buttons: AC, A,
// (empty), and division operator
Row(
children: [
button("AC", Colors.black, Colors.orangeAccent),
button("A", Colors.black, Colors.orangeAccent),
button("", Colors.transparent, Colors.white),
button("/", Colors.black, Colors.orangeAccent),
],
),
// Second row of buttons: 7, 8, 9,
// and multiplication operator
Row(
children: [
button("7", Colors.black, Colors.white),
button("8", Colors.black, Colors.white),
button("9", Colors.black, Colors.white),
button("*", Colors.black, Colors.orangeAccent),
],
),
// Third row of buttons: 4, 5, 6,
// and subtraction operator
Row(
children: [
button("4", Colors.black, Colors.white),
button("5", Colors.black, Colors.white),
button("6", Colors.black, Colors.white),
button("-", Colors.black, Colors.orangeAccent),
],
),
// Fourth row of buttons: 1, 2, 3,
// and addition operator
Row(
children: [
button("1", Colors.black, Colors.white),
button("2", Colors.black, Colors.white),
button("3", Colors.black, Colors.white),
button("+", Colors.black, Colors.orangeAccent),
],
),
// Fifth row of buttons: %, 0, .,
// and equals operator
Row(
children: [
button("%", Colors.black, Colors.orangeAccent),
button("0", Colors.black, Colors.white),
button(".", Colors.black, Colors.white),
button("=", Colors.orangeAccent, Colors.white),
],
),
],
),
);
}
// Helper function to create a calculator button
button(text, color, tcolor) {
return Expanded(
// Expanded makes the button fill
// available horizontal space
child: Container(
// Padding around the button
padding: EdgeInsets.all(10),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
// Padding inside the button
padding: EdgeInsets.all(10),
// Button background color
backgroundColor: color,
shape: RoundedRectangleBorder(
// Rounded corners
borderRadius: BorderRadius.circular(5),
),
),
// Call _onButtonClicked with the
// button's text when pressed
onPressed: () => _onButtonClicked(text),
child: Text(
text,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
// Text color
color: tcolor,
),
),
),
),
);
}
}