Calculator

4.4
Serik.Uvaissov 2020-05-29 22:47:58 +06:00
parent 9c9dc94f1b
commit f955ff8d71
6 changed files with 212 additions and 0 deletions

View File

@ -0,0 +1,32 @@
import 'package:flutter/material.dart';
typedef void CalculatorButtonTapCallback({String buttonText});
class CalculatorButton extends StatelessWidget {
CalculatorButton({this.text, @required this.onTap});
final String text;
final CalculatorButtonTapCallback onTap;
@override
Widget build(BuildContext context) {
return Expanded(
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: Color.fromRGBO(0, 0, 0, 0.1),
width: 0.5,
),
),
child: FlatButton(
onPressed: () => onTap(buttonText: text),
child: Text(
text,
style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500),
),
padding: EdgeInsets.all(30),
highlightColor: Colors.blueGrey[100],
splashColor: Colors.blueAccent[100],
)));
}
}

View File

@ -0,0 +1,29 @@
import 'package:flutter/material.dart';
import 'calculator.dart';
import 'calculator-button.dart';
import 'calculator-row.dart';
class CalculatorButtons extends StatelessWidget {
CalculatorButtons({@required this.onTap});
final CalculatorButtonTapCallback onTap;
final calculatorButtonRows = [
['7', '8', '9', Calculations.DIVIDE],
['4', '5', '6', Calculations.MULTIPLY],
['1', '2', '3', Calculations.SUBTRACT],
[Calculations.PERIOD, '0', '00', Calculations.ADD],
[Calculations.CLEAR, Calculations.EQUAL]
];
@override
Widget build(BuildContext context) {
return Column(
children: calculatorButtonRows.map((calculatorRowButtons) {
return CalculatorRow(
buttons: calculatorRowButtons,
onTap: onTap,
);
}).toList()
);
}
}

View File

@ -0,0 +1,32 @@
import 'package:flutter/material.dart';
import 'calculator-button.dart';
class CalculatorRow extends StatelessWidget {
CalculatorRow({@required this.buttons, @required this.onTap });
final List<String> buttons;
final CalculatorButtonTapCallback onTap;
@override
Widget build(BuildContext context) {
return Row(
children: rowButtons(),
mainAxisAlignment: MainAxisAlignment.spaceAround,
);
}
List<Widget> rowButtons() {
List<Widget> rowButtons = [];
buttons.forEach((String buttonText) {
rowButtons.add(
CalculatorButton(
text: buttonText,
onTap: onTap,
),
);
});
return rowButtons;
}
}

View File

@ -0,0 +1,82 @@
import 'number-formatter.dart';
class Calculations {
static const PERIOD = '.';
static const MULTIPLY = '*';
static const SUBTRACT = '-';
static const ADD = '+';
static const DIVIDE = '/';
static const CLEAR = 'CLEAR';
static const EQUAL = '=';
static const OPERATIONS = [
Calculations.ADD,
Calculations.MULTIPLY,
Calculations.SUBTRACT,
Calculations.DIVIDE,
];
static double add(double a, double b) => a + b;
static double subtract(double a, double b) => a - b;
static double divide(double a, double b) => a / b;
static double multiply(double a, double b) => a * b;
}
class Calculator {
static String parseString(String text) {
List<String> numbersToAdd;
double a, b, result;
if (text.contains(Calculations.ADD)) {
numbersToAdd = text.split(Calculations.ADD);
a = double.parse(numbersToAdd[0]);
b = double.parse(numbersToAdd[1]);
result = Calculations.add(a, b);
} else if (text.contains(Calculations.MULTIPLY)) {
numbersToAdd = text.split(Calculations.MULTIPLY);
a = double.parse(numbersToAdd[0]);
b = double.parse(numbersToAdd[1]);
result = Calculations.multiply(a, b);
} else if (text.contains(Calculations.DIVIDE)) {
numbersToAdd = text.split(Calculations.DIVIDE);
a = double.parse(numbersToAdd[0]);
b = double.parse(numbersToAdd[1]);
result = Calculations.divide(a, b);
} else if (text.contains(Calculations.SUBTRACT)) {
numbersToAdd = text.split(Calculations.SUBTRACT);
a = double.parse(numbersToAdd[0]);
b = double.parse(numbersToAdd[1]);
result = Calculations.subtract(a, b);
} else {
return text;
}
return NumberFormatter.format(result.toString());
}
static String addPeriod(String calculatorString) {
if (calculatorString.isEmpty) {
return calculatorString = '0${Calculations.PERIOD}';
}
RegExp exp = new RegExp(r"\d\.");
Iterable<Match> matches = exp.allMatches(calculatorString);
int maxMatches = Calculator.includesOperation(calculatorString) ? 2 : 1;
return matches.length == maxMatches
? calculatorString
: calculatorString += Calculations.PERIOD;
}
static bool includesOperation(String calculatorString) {
for (var operation in Calculations.OPERATIONS) {
if (calculatorString.contains(operation)) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,22 @@
import 'package:flutter/material.dart';
class NumberDisplay extends StatelessWidget {
NumberDisplay({this.value: ''});
final String value;
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(20),
child: Row(
children: <Widget>[
Text(
value,
style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold),
),
],
mainAxisAlignment: MainAxisAlignment.end,
));
}
}

View File

@ -0,0 +1,15 @@
class NumberFormatter {
static String format(String text) {
try {
double parsedNumber = double.parse(text);
if ((parsedNumber != double.infinity) && (parsedNumber == parsedNumber.floor())) {
return parsedNumber.truncate().toString();
}
return text;
} catch(err) {
return text;
}
}
}