Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Flutter Calculator
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: CalculatorScreen(),
);
}
}
class CalculatorScreen extends StatefulWidget {
@override
_CalculatorScreenState createState() => _CalculatorScreenState();
}
class _CalculatorScreenState extends State<CalculatorScreen> {
String _output = '0';
String _stage = '0';
CalcState _state = CalcState.normal;
bool _showResult = true;
void _append(String val) {
if (mounted)
setState(() {
if (!_showResult) {
if (_stage == '0') _stage = '';
if (val == '.' && _stage.contains('.')) return;
_stage += val;
} else {
if (_output == '0') _output = '';
if (val == '.' && _output.contains('.')) return;
_output += val;
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Calculator'),
),
body: Container(
color: Colors.black,
child: Column(
children: [
Container(
height: 100,
width: double.infinity,
alignment: Alignment.centerRight,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Text(
!_showResult ? _stage : _output,
maxLines: 1,
textAlign: TextAlign.end,
style: TextStyle(
color: Colors.white,
fontSize: 50,
),
),
),
),
Expanded(
child: LayoutBuilder(
builder: (_, dimens) {
final size = Size(
(dimens.maxWidth / 4) - 8, (dimens.maxHeight / 5) - 8);
return DefaultTextStyle(
style: TextStyle(fontSize: 30, color: Colors.black),
child: Wrap(
children: [
CalcButton(
child: Center(child: Text('AC')),
color: Colors.grey,
width: size.width,
height: size.height,
onTap: () {
if (mounted)
setState(() {
_output = '0';
_stage = '0';
_state = CalcState.normal;
});
},
),
CalcButton(
child: Center(child: Text('+/-')),
color: Colors.grey,
width: size.width,
height: size.height,
onTap: () {
if (mounted)
setState(() {
if (_showResult) {
if (_output.contains('-') || _output == '0') {
_output = _output.replaceAll('-', '');
} else {
_output = '-' + _output;
}
} else {
if (_stage.contains('-') || _stage == '0') {
_stage = _stage.replaceAll('-', '');
} else {
_stage = '-' + _stage;
}
}
});
},
),
CalcButton(
child: Center(child: Text('%')),
color: Colors.grey,
width: size.width,
height: size.height,
onTap: () {
if (mounted)
setState(() {
if (_showResult) {
final _result = num.tryParse(_output) / 100;
_output = _result.toString();
} else {
final _result = num.tryParse(_stage) / 100;
_stage = _result.toString();
}
});
},
),
CalcButton(
child: Center(
child: Text('/',
style: TextStyle(color: Colors.white))),
color: Colors.amber,
width: size.width,
height: size.height,
onTap: () {
if (mounted)
setState(() {
_showResult = false;
_state = CalcState.divide;
});
},
),
_num(size, 7),
_num(size, 8),
_num(size, 9),
CalcButton(
child: Center(
child: Text('X',
style: TextStyle(color: Colors.white))),
color: Colors.amber,
width: size.width,
height: size.height,
onTap: () {
if (mounted)
setState(() {
_showResult = false;
_state = CalcState.multiply;
});
},
),
_num(size, 4),
_num(size, 5),
_num(size, 6),
CalcButton(
child: Center(
child: Text('-',
style: TextStyle(color: Colors.white))),
color: Colors.amber,
width: size.width,
height: size.height,
onTap: () {
if (mounted)
setState(() {
_showResult = false;
_state = CalcState.subtract;
});
},
),
_num(size, 1),
_num(size, 2),
_num(size, 3),
CalcButton(
child: Center(
child: Text('+',
style: TextStyle(color: Colors.white))),
color: Colors.amber,
width: size.width,
height: size.height,
onTap: () {
if (mounted)
setState(() {
_showResult = false;
_state = CalcState.add;
});
},
),
CalcButton(
doubleWidth: true,
child: Container(
padding:
EdgeInsets.only(left: (size.width / 2) - 8),
alignment: Alignment.centerLeft,
child: Text('0',
style: TextStyle(color: Colors.white))),
color: Colors.grey.shade800,
width: size.width,
height: size.height,
onTap: () => _append('0'),
),
CalcButton(
child: Center(
child: Text('.',
style: TextStyle(color: Colors.white))),
color: Colors.grey.shade800,
width: size.width,
height: size.height,
onTap: () => _append('.'),
),
CalcButton(
child: Center(
child: Text('=',
style: TextStyle(color: Colors.white))),
color: Colors.amber,
width: size.width,
height: size.height,
onTap: () {
String _result;
final a = num.tryParse(_output);
final b = num.tryParse(_stage);
switch (_state) {
case CalcState.normal:
_result = _output;
break;
case CalcState.add:
_result = (a + b).toString();
break;
case CalcState.divide:
_result = (a / b).toString();
break;
case CalcState.multiply:
_result = (a * b).toString();
break;
case CalcState.subtract:
_result = (a - b).toString();
break;
}
if (mounted)
setState(() {
_showResult = true;
_output = _result;
});
},
),
],
),
);
},
),
),
],
),
),
);
}
Widget _num(Size size, int val) {
return CalcButton(
child: Center(child: Text('$val', style: TextStyle(color: Colors.white))),
color: Colors.grey.shade800,
width: size.width,
height: size.height,
onTap: () => _append('$val'),
);
}
}
enum CalcState {
normal,
add,
divide,
multiply,
subtract,
}
class CalcButton extends StatelessWidget {
const CalcButton({
Key key,
@required this.width,
this.color,
this.onTap,
this.child,
this.height,
this.doubleWidth = false,
}) : super(key: key);
final double width, height;
final Color color;
final VoidCallback onTap;
final Widget child;
final bool doubleWidth;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Container(
width: (doubleWidth ? width + 8 : 0) + width,
height: height,
margin: EdgeInsets.all(4),
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(width),
),
child: child,
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.