Tag: caculator

  • Flutter 範例專案 Caculator 計算機 App

    Flutter 範例專案 Caculator 計算機 App

    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,
    ]
    ),
    ),
    );
    }
    }