Giter Club home page Giter Club logo

flutter-calculator's Introduction

Flutter-Calculator

flutterの学習用に作成したスマートフォン用のシンプルな電卓アプリ

Note

ClassDiagram
classDiagram
    class MyApp {
        +build(BuildContext context)
    }

    class CalculatorPage {
        +build(BuildContext context)
    }

    class _CalculatorTextDisplay {
        -ValueNotifier<String> calcText
        -ValueNotifier<String> logText
        +build(BuildContext context)
    }

    class _CalculatorButtons {
        -ValueNotifier<String> calcText
        -ValueNotifier<String> logText
        +build(BuildContext context)
    }

    class CalculatorButton {
        -String buttonText
        -ValueNotifier<String> calcText
        -ValueNotifier<String> logText
        +build(BuildContext context)
    }

    class TextCalculator {
        +calculator(ValueNotifier<String> text)
        +bracketsText(ValueNotifier<String> text)
        +incrementText(String incrementText, ValueNotifier<String> text)
        +decrementText(ValueNotifier<String> text)
        +clearText(ValueNotifier<String> text)
        +saveLog(String saveText, ValueNotifier<String> text)
        +loadLog(ValueNotifier<String> saveText, ValueNotifier<String> text)
    }

    MyApp --> CalculatorPage
    CalculatorPage --> _CalculatorTextDisplay
    CalculatorPage --> _CalculatorButtons
    _CalculatorButtons --> CalculatorButton
    CalculatorButton --> TextCalculator
Loading
SequenceDiagram
sequenceDiagram
    participant User
    participant CalculatorButton
    participant TextCalculator

    User ->> CalculatorButton: onPressed("buttonText")
    CalculatorButton ->> TextCalculator: calculatorButtonSwitch(buttonText, calcText, logText)
    alt buttonText is a number or operator
        TextCalculator ->> calcText: incrementText(buttonText)
    else buttonText is "( )"
        TextCalculator ->> calcText: bracketsText(calcText)
    else buttonText is "C"
        TextCalculator ->> calcText: decrementText(calcText)
    else buttonText is "AC"
        TextCalculator ->> calcText: clearText(calcText)
        TextCalculator ->> logText: clearText(logText)
    else buttonText is "<"
        TextCalculator ->> calcText: loadLog(logText, calcText)
    else buttonText is "="
        TextCalculator ->> logText: saveLog(calcText.value, logText)
        TextCalculator ->> calcText: calculator(calcText)
    end
Loading

external package

使用した外部パッケージ

flutter-calculator's People

Contributors

itc-s22020 avatar

Watchers

 avatar

flutter-calculator's Issues

calculator_page.dartにすべての機能が実装されているので分割する

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:math_expressions/math_expressions.dart';
class CalculatorPage extends HookWidget {
const CalculatorPage({super.key});
void calculator(ValueNotifier<String> text) {
final calcText = text.value.replaceAll("÷", "/").replaceAll("×", "*");
Parser p = Parser();
clearText(text);
try {
Expression exp = p.parse(calcText);
double calc = exp.evaluate(EvaluationType.REAL,ContextModel());
RegExp reg = RegExp(r'\.0+$'); //正規表現で少数以下がない場合破棄
incrementText(calc.toString().replaceAll(reg, ""), text);
} catch(e) {
incrementText("Error", text);
return;
}
}
void incrementText(String incrementText, ValueNotifier<String> text) {
if(text.value == "Error") {
clearText(text);
}
text.value += incrementText;
}
void decrementText(ValueNotifier<String> text) {
final pos = text.value.length - 1;
if (pos >= 0) {
text.value = text.value.substring(0,pos);
}
}
void bracketsText(ValueNotifier<String> text) {
final textValue = text.value;
final length = textValue.length;
final leftBracketIndex = textValue.lastIndexOf("(");
final rightBracketIndex = textValue.lastIndexOf(")");
final leftBracketCount = length - textValue.replaceAll("(", "").length;
final rightBracketCount = length - textValue.replaceAll(")", "").length;
if (textValue.isEmpty || leftBracketCount == 0) {
incrementText("(", text);
} else if(length-1==leftBracketIndex) {
incrementText("(", text);
} else if(leftBracketCount > rightBracketCount) {
incrementText(")", text);
} else if(leftBracketIndex < rightBracketIndex){
incrementText("(", text);
} else{
incrementText(")", text);
}
}
void clearText(ValueNotifier<String> text) {
text.value = "";
}
void saveLog(String saveText,ValueNotifier<String> text) {
text.value = saveText;
}
void loadLog(ValueNotifier<String> saveText, ValueNotifier<String> text) {
text.value = saveText.value;
}
void calculatorButtonSwitch(String buttonText, ValueNotifier<String> text, ValueNotifier<String> logText) {
switch(buttonText) {
case "0":
case "1":
case "2":
case "3":
case "4":
case "5":
case "6":
case "7":
case "8":
case "9":
case "+":
case "-":
case "×":
case "÷":
case ".":
incrementText(buttonText, text);
break;
case "( )":
bracketsText(text);
break;
case "C":
decrementText(text);
break;
case "AC":
clearText(text);
break;
case "<":
loadLog(logText, text);
break;
case "=":
saveLog(text.value, logText);
calculator(text);
case _:
calculator(text);
break;
}
}
@override
Widget build(BuildContext context)
{
final calcText = useState<String>("");
final logText = useState<String>("");
final List<String> textList =
[
"AC","( )","<" ,"÷",
"7" , "8" ,"9" ,"×",
"4" , "5" ,"6" ,"-",
"1" , "2" ,"3" ,"+",
"0" , "." ,"C" ,"=",
];
List<Widget> buttonList = [];
for (String text in textList)
{
buttonList.add(
_calculatorButton(text, calcText, logText)
);
}
return MaterialApp(
home: Scaffold(
body: ScreenUtilInit(
designSize: const Size(300, 600),
builder: (_, child) => Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
alignment: Alignment.center,
width: 200.w,
height: 210.h,
decoration: const BoxDecoration(
color: Colors.black12,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(50),
bottomRight: Radius.circular(50),
),
),
child:Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: const EdgeInsets.only(left: 10,right: 10),
alignment: Alignment.bottomRight,
child: AutoSizeText(
logText.value,
style: const TextStyle(
fontSize: 30,
color: Colors.grey
),
maxLines: 1,
),
),
Container(
alignment: Alignment.topRight,
padding: EdgeInsets.only(bottom: 0.h,left: 5.h,right: 5.h,top: 0),
child: AutoSizeText(
calcText.value,
style: const TextStyle(
fontSize: 90,
),
maxLines: 1,
),
)
],
)
),
Expanded(
child:Container(
alignment: Alignment.center,
child: GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(), //スクロール無効
itemCount: buttonList.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
mainAxisSpacing: 5,
crossAxisSpacing: 5,
),
padding: const EdgeInsets.all(8),
itemBuilder: (BuildContext context, int index) {
return buttonList[index];
},
),
)
)
]
)
),
)
)
);
}
Widget _calculatorButton(String buttonText, ValueNotifier<String> calcText, ValueNotifier<String> logText) {
return ElevatedButton(
onPressed: () {
calculatorButtonSwitch(buttonText, calcText, logText);
},
child: Text(
buttonText,
style: const TextStyle(fontSize: 35),
),
);
}
}

階層構造になりすぎて見にくいので分割したい

return MaterialApp(
home: Scaffold(
body: ScreenUtilInit(
designSize: const Size(300, 600),
builder: (_, child) => Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
alignment: Alignment.center,
width: 200.w,
height: 210.h,
decoration: const BoxDecoration(
color: Colors.black12,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(50),
bottomRight: Radius.circular(50),
),
),
child:Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: const EdgeInsets.only(left: 10,right: 10),
alignment: Alignment.bottomRight,
child: AutoSizeText(
logText.value,
style: const TextStyle(
fontSize: 30,
color: Colors.grey
),
maxLines: 1,
),
),
Container(
alignment: Alignment.topRight,
padding: EdgeInsets.only(bottom: 0.h,left: 5.h,right: 5.h,top: 0),
child: AutoSizeText(
calcText.value,
style: const TextStyle(
fontSize: 90,
),
maxLines: 1,
),
)
],
)
),
Expanded(
child:Container(
alignment: Alignment.center,
child: GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(), //スクロール無効
itemCount: buttonList.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
mainAxisSpacing: 5,
crossAxisSpacing: 5,
),
padding: const EdgeInsets.all(8),
itemBuilder: (BuildContext context, int index) {
return buttonList[index];
},
),
)
)
]
)
),
)
)
);
}

冗長に見えるcaseを修正したい

void calculatorButtonSwitch(String buttonText, ValueNotifier<String> text, ValueNotifier<String> logText) {
switch(buttonText) {
case "0":
case "1":
case "2":
case "3":
case "4":
case "5":
case "6":
case "7":
case "8":
case "9":
case "+":
case "-":
case "×":
case "÷":
case ".":
incrementText(buttonText, text);
break;
case "( )":
bracketsText(text);
break;
case "C":
decrementText(text);
break;
case "AC":
clearText(text);
break;
case "<":
loadLog(logText, text);
break;
case "=":
saveLog(text.value, logText);
calculator(text);
case _:
calculator(text);
break;
}
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.