A Caculator App project for demonstrating Flutter.

main.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:caculator/daos/cacu_dao.dart';
import 'package:caculator/daos/value_viewer_dao.dart';
import 'package:caculator/screens/caculate_screen.dart';
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_)=> CacuDao()),
ChangeNotifierProvider(create: (_) => ValueViewerDao())],
child: const AppEntryPoint()
)
);
}
class AppEntryPoint extends StatelessWidget {
const AppEntryPoint({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Caculator',
theme: ThemeData(
primarySwatch: Colors.blueGrey,
),
routes: {
"/caculate":(BuildContext context) => CaculateScreen(),
},
initialRoute: "/caculate",
);
}
}
models\cacu.dart
class Cacu {
String cacuValue; // Value for caculate
CacuType cacuType; // Caculate type
Cacu(this.cacuValue, this.cacuType);
}
enum CacuType {
none,
addition,
subtraction,
multiplication,
division,
}
daos\cacu_dao.dart
import 'package:flutter/material.dart';
import 'package:caculator/models/cacu.dart';
class CacuDao extends ChangeNotifier {
List<Cacu> cacuList = [];
List<Cacu> getCacus() {
return cacuList;
}
/// Insert value for caculate later
void insertCacu(Cacu cacu) {
cacuList.add(cacu);
notifyListeners();
}
/// Update caculate type to value
void clearCacu() {
cacuList.clear();
notifyListeners();
}
}
daos\value_viewer_dao.dart
import 'package:flutter/material.dart';
class ValueViewerDao extends ChangeNotifier {
double value = 0;
/// Update caculate type to value
void updateValue(double value) {
this.value = value;
notifyListeners();
}
}
components\common_functions.dart
import 'package:caculator/models/cacu.dart';
class CommonFunctions {
static String getCacuSign(CacuType cacuType) {
switch (cacuType) {
case CacuType.addition:
return "+";
case CacuType.subtraction:
return "-";
case CacuType.multiplication:
return "x";
case CacuType.division:
return "÷";
default:
return "";
}
}
}
cacu_component.dart
import 'package:flutter/material.dart';
import 'package:caculator/models/cacu.dart';
import 'package:caculator/components/common_functions.dart';
// ignore: must_be_immutable
class CacuComponent extends StatefulWidget {
Cacu cacu;
CacuComponent(this.cacu, {super.key});
@override
State createState() {
return _CacuComponent();
}
}
class _CacuComponent extends State<CacuComponent> {
@override
Widget build(BuildContext context) {
Widget cacuValueText = Text(
widget.cacu.cacuValue,
);
Widget cacuTypeText = Text(
CommonFunctions.getCacuSign(widget.cacu.cacuType),
);
return Card(
child: ListTile(
title: Row(children: [
cacuValueText,
const SizedBox(width: 10),
cacuTypeText,
]),
),
);
}
}
screens\caculate_screen.dart
import 'dart:async';
import 'package:caculator/components/common_functions.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:caculator/daos/cacu_dao.dart';
import 'package:caculator/components/cacu_component.dart';
import 'package:caculator/models/cacu.dart';
// ignore: must_be_immutable
class CaculateScreen extends StatefulWidget {
CaculateScreen({super.key});
Cacu currentCacu = Cacu('0', CacuType.none);
@override
State createState() {
return _CaculateScreen();
}
}
class _CaculateScreen extends State<CaculateScreen> {
final ScrollController _scrollController = ScrollController();
@override
Widget build(BuildContext context) {
Timer(const Duration(milliseconds: 500), () => _scrollController.jumpTo(_scrollController.position.maxScrollExtent));
Widget valueViewer = Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 250,
margin: const EdgeInsets.all(15.0),
padding: const EdgeInsets.all(3.0),
decoration: BoxDecoration(
border: Border.all(color: Colors.blueAccent)
),
child: Text(
widget.currentCacu.cacuValue,
textAlign: TextAlign.right,
style: const TextStyle(fontSize: 20),),
),
Text(CommonFunctions.getCacuSign(widget.currentCacu.cacuType)),
],
);
Widget keybooards = Column(children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 70.0,
child: OutlinedButton(
child: const Text('AC',
overflow: TextOverflow.clip,
maxLines: 1,
softWrap: false,
),
onPressed: (){
setState(() {
widget.currentCacu = Cacu('0', CacuType.none);
context.read<CacuDao>().clearCacu();
});
},
)
),
const SizedBox(width: 5),
OutlinedButton(
child: const Text('C'),
onPressed: (){
setState(() {
widget.currentCacu = Cacu('0', CacuType.none);
});
},
),
const SizedBox(width: 5),
OutlinedButton(
child: const Text('±'),
onPressed: (){
setState(() {
if(widget.currentCacu.cacuValue[0] == '-'){
widget.currentCacu.cacuValue = widget.currentCacu.cacuValue.substring(1);
}
else {
widget.currentCacu.cacuValue = '-${widget.currentCacu.cacuValue}';
}
});
},
),
const SizedBox(width: 5),
OutlinedButton(
child: const Text('÷'),
onPressed: (){
setState(() {
widget.currentCacu.cacuType = CacuType.division;
});
}
),
]
),
const SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
OutlinedButton(
child: const Text('7'),
onPressed: (){
setState(() {
String num = '7';
if(widget.currentCacu.cacuType == CacuType.none) {
if(widget.currentCacu.cacuValue == '0') {
widget.currentCacu.cacuValue = num;
} else {
widget.currentCacu.cacuValue = widget.currentCacu.cacuValue + num;
}
}
else {
context.read<CacuDao>().insertCacu(widget.currentCacu);
widget.currentCacu = Cacu(num, CacuType.none);
}
});
}
),
const SizedBox(width: 5),
OutlinedButton(
child: const Text('8'),
onPressed: (){
setState(() {
String num = '8';
if(widget.currentCacu.cacuType == CacuType.none) {
if(widget.currentCacu.cacuValue == '0') {
widget.currentCacu.cacuValue = num;
} else {
widget.currentCacu.cacuValue = widget.currentCacu.cacuValue + num;
}
}
else {
context.read<CacuDao>().insertCacu(widget.currentCacu);
widget.currentCacu = Cacu(num, CacuType.none);
}
});
}
),
const SizedBox(width: 5),
OutlinedButton(
child: const Text('9'),
onPressed: (){
setState(() {
String num = '9';
if(widget.currentCacu.cacuType == CacuType.none) {
if(widget.currentCacu.cacuValue == '0') {
widget.currentCacu.cacuValue = num;
} else {
widget.currentCacu.cacuValue = widget.currentCacu.cacuValue + num;
}
}
else {
context.read<CacuDao>().insertCacu(widget.currentCacu);
widget.currentCacu = Cacu('0', CacuType.none);
}
});
}
),
const SizedBox(width: 10),
OutlinedButton(
child: const Text('x'),
onPressed: (){
setState(() {
widget.currentCacu.cacuType = CacuType.multiplication;
});
}
),
],
),
const SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
OutlinedButton(
child: const Text('4'),
onPressed: (){
setState(() {
String num = '4';
if(widget.currentCacu.cacuType == CacuType.none) {
if(widget.currentCacu.cacuValue == '0') {
widget.currentCacu.cacuValue = num;
} else {
widget.currentCacu.cacuValue = widget.currentCacu.cacuValue + num;
}
}
else {
context.read<CacuDao>().insertCacu(widget.currentCacu);
widget.currentCacu = Cacu(num, CacuType.none);
}
});
}
),
const SizedBox(width: 5),
OutlinedButton(
child: const Text('5'),
onPressed: (){
setState(() {
String num = '5';
if(widget.currentCacu.cacuType == CacuType.none) {
if(widget.currentCacu.cacuValue == '0') {
widget.currentCacu.cacuValue = num;
} else {
widget.currentCacu.cacuValue = widget.currentCacu.cacuValue + num;
}
}
else {
context.read<CacuDao>().insertCacu(widget.currentCacu);
widget.currentCacu = Cacu(num, CacuType.none);
}
});
}
),
const SizedBox(width: 5),
OutlinedButton(
child: const Text('6'),
onPressed: (){
setState(() {
String num = '6';
if(widget.currentCacu.cacuType == CacuType.none) {
if(widget.currentCacu.cacuValue == '0') {
widget.currentCacu.cacuValue = num;
} else {
widget.currentCacu.cacuValue = widget.currentCacu.cacuValue + num;
}
}
else {
context.read<CacuDao>().insertCacu(widget.currentCacu);
widget.currentCacu = Cacu(num, CacuType.none);
}
});
}
),
const SizedBox(width: 10),
OutlinedButton(
child: const Text('-'),
onPressed: (){
setState(() {
widget.currentCacu.cacuType = CacuType.subtraction;
});
}
),
],
),
const SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
OutlinedButton(
child: const Text('1'),
onPressed: (){
setState(() {
String num = '1';
if(widget.currentCacu.cacuType == CacuType.none) {
if(widget.currentCacu.cacuValue == '0') {
widget.currentCacu.cacuValue = num;
} else {
widget.currentCacu.cacuValue = widget.currentCacu.cacuValue + num;
}
}
else {
context.read<CacuDao>().insertCacu(widget.currentCacu);
widget.currentCacu = Cacu(num, CacuType.none);
}
});
}
),
const SizedBox(width: 5),
OutlinedButton(
child: const Text('2'),
onPressed: (){
setState(() {
String num = '2';
if(widget.currentCacu.cacuType == CacuType.none) {
if(widget.currentCacu.cacuValue == '0') {
widget.currentCacu.cacuValue = num;
} else {
widget.currentCacu.cacuValue = widget.currentCacu.cacuValue + num;
}
}
else {
context.read<CacuDao>().insertCacu(widget.currentCacu);
widget.currentCacu = Cacu(num, CacuType.none);
}
});
}
),
const SizedBox(width: 5),
OutlinedButton(
child: const Text('3'),
onPressed: (){
setState(() {
String num = '3';
if(widget.currentCacu.cacuType == CacuType.none) {
if(widget.currentCacu.cacuValue == '0') {
widget.currentCacu.cacuValue = num;
} else {
widget.currentCacu.cacuValue = widget.currentCacu.cacuValue + num;
}
}
else {
context.read<CacuDao>().insertCacu(widget.currentCacu);
widget.currentCacu = Cacu(num, CacuType.none);
}
});
}
),
const SizedBox(width: 10),
OutlinedButton(
child: const Text('+'),
onPressed: (){
setState(() {
widget.currentCacu.cacuType = CacuType.addition;
});
}
),
],
),
const SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 130.0,
child: OutlinedButton(
child: const Text('0'),
onPressed: (){
setState(() {
String num = '0';
if(widget.currentCacu.cacuType == CacuType.none) {
if(widget.currentCacu.cacuValue != '0' && !widget.currentCacu.cacuValue.contains('.')) {
widget.currentCacu.cacuValue = widget.currentCacu.cacuValue + num;
}
}
else {
context.read<CacuDao>().insertCacu(widget.currentCacu);
widget.currentCacu = Cacu(num, CacuType.none);
}
});
}
),
),
const SizedBox(width: 5),
OutlinedButton(
child: const Text('.'),
onPressed: (){
String num = '.';
if(widget.currentCacu.cacuType == CacuType.none) {
if(!widget.currentCacu.cacuValue.contains('.')) {
widget.currentCacu.cacuValue = widget.currentCacu.cacuValue + num;
}
}
else {
context.read<CacuDao>().insertCacu(widget.currentCacu);
widget.currentCacu = Cacu('0', CacuType.none);
}
}
),
const SizedBox(width: 10),
OutlinedButton(
child: const Text('='),
onPressed: (){
setState(() {
double result = 0;
CacuType lastCacuType = CacuType.none;
List<Cacu> cacus = context.read<CacuDao>().getCacus();
cacus.add(Cacu(widget.currentCacu.cacuValue, CacuType.none));
for (var cacu in cacus) {
switch(lastCacuType) {
case CacuType.division:
result = result / double.parse(cacu.cacuValue);
case CacuType.multiplication:
result = result * double.parse(cacu.cacuValue);
case CacuType.subtraction:
result = result - double.parse(cacu.cacuValue);
case CacuType.addition:
result = result + double.parse(cacu.cacuValue);
default:
result = double.parse(cacu.cacuValue);
}
lastCacuType = cacu.cacuType;
}
widget.currentCacu = Cacu(result.toString(), CacuType.none);
context.read<CacuDao>().clearCacu();
});
}
),
],
),
const SizedBox(height: 5),
]);
return Scaffold(
appBar: AppBar(title: const Text("Caculator"),),
body: Container(
alignment: Alignment.topCenter,
child: Column(
children: [
Expanded(
child: ListView(
controller: _scrollController,
children: [
...context.watch<CacuDao>().getCacus().map((e) => CacuComponent(e)).toList(),
],
),
),
valueViewer,
keybooards,
]
),
),
);
}
}


Leave a comment