이번 주차에는 Flutter를 이용하여 기본적인 기능에 충실한 간단한 계산기 앱을 만들어보겠습니다. 이 앱은 덧셈, 뺄셈, 곱셈, 나눗셈 기능만 가능한 아주 간단한 앱입니다. 이번 프로젝트를 통해 Flutter의 상태관리, 및 기본 위젯을 활용하는 방법을 알아 보겠습니다.
1. 프로젝트 생성
- VSCode를 열고, Ctrl+Shift+P 단축 키를 이용하여 Command Palette를 엽니다.

2. Flutter: New Project를 선택하고 프로젝트를 생성할 디렉토리를 선택합니다.

3. 프로젝트 이름을 ‘calcurator_app’으로 입력합니다.


2. 계산기 앱 만들기
이번 계산기 앱은 다음과 같은 구조로 클래스를 나눠 구현했습니다.
- main.dart: 앱의 시작점으로 ‘MyApp’ 클래스를 정의
- calcurator_home.dart: 계산기의 메인화면을 구성하는 위젯을 정의
- calcurator_button.dart: 계산기의 버튼 위젯을 정의
main.dart 하나의 파일에 모두 작성할 수 있지만 유지보수성을 높이고, 재사용이 편하도록 클래스 별로 나눠서 작성했습니다.
3. main.dart
lib/main.dart 파일에는 앱은 시작(진입점)과 전체 앱의 테마를 정의합니다.
main.dart파일을 열고 다음과 같이 수정합니다.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Calcurator App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
);
}
}
아직 앱의 메인 화면인 Home을 정의하지 않아 앱을 실행 시키면 빈 화면만 나올 것입니다.

4. calculator_button.dart 작성
가장 먼저 CalcuratorButton 클래스를 작성합니다. 이 클래스는 버튼을 구성하는 데 사용됩니다.
- lib 디렉토리 아래 calcurator_button.dart 파일을 생성합니다.
- 다음 코드를 작성합니다.
import 'package:flutter/material.dart';
//CalcuratorButton 클래스는 계산기의 버튼을 정의하는 위젯입니다.
class CalcuratorButton extends StatelessWidget {
final String buttonText;
final Function buttonCallback;
//CalcuratorButton 생성자는 버튼의 텍스트와 콜백 함수를 받아옵니다.
CalcuratorButton(this.buttonText, this.buttonCallback);
@override
Widget build(BuildContext context) {
return Expanded(
child: OutlinedButton(
onPressed: () => buttonCallback(buttonText),
child: Text(
buttonText,
style: TextStyle(fontSize: 20.0),
),
),
);
}
}
5. CalcuratorHomePage 클래스 작성
CalcuratorButton 클래스를 작성한 후, 이제 메인 화면을 구성하는 CalcuratorHomePage 클래스를 작성합니다.
- lib 디렉토리 아래에 calcurator_home.dart 파일을 생성합니다.
- 다음 코드를 CalcuratorHomePage.dart에 작성합니다.
import 'package:flutter/material.dart';
import 'calcurator_button.dart';
class CalcuratorHomePage extends StatefulWidget {
@override
_CalcuratorHomePageState createState() => _CalcuratorHomePageState();
}
class _CalcuratorHomePageState extends State<CalcuratorHomePage> {
String output = "0"; //화면에 표시될 계산 결과 값
String _output = "0";
double num1 = 0.0;
double num2 = 0.0;
String operand = "";
//버튼이 눌렸을 때 호출되는 함수
buttonPressed(String buttonText) {
if (buttonText == "CLEAR") {
//모든 값을 초기화 합니다.
_output = "0";
num1 = 0.0;
num2 = 0.0;
operand = "";
} else if (buttonText == "+" ||
buttonText == "-" ||
buttonText == "x" ||
buttonText == "/") {
//연산자를 선택하고 첫 번째 숫자를 저장합니다.
num1 = double.parse(output);
operand = buttonText;
_output = "0";
} else if (buttonText == ".") {
//소수점이 이미 포함되어 있으면 추가하지 않습니다.
if (output.contains(".")) {
return;
} else {
_output += buttonText; // 소수점
}
} else if (buttonText == "=") {
//두 번째 숫자를 저장하고 계산을 합니다.
num2 = double.parse(output);
if (operand == "+") {
_output = (num1 + num2).toString();
} else if (operand == "-") {
_output = (num1 - num2).toString();
} else if (operand == "x") {
_output = (num1 * num2).toString();
} else if (operand == "/") {
_output = (num1 / num2).toString();
}
//계산이 끝난 후 초기화
num1 = 0.0;
num2 = 0.0;
operand = "";
} else {
// 숫자를 입력할 때마다 현재 출력 값에 추가 합니다.
_output += buttonText;
}
//UI를 업데이트하고 계산 결과를 표시합니다.
setState(() {
output = double.parse(_output).toStringAsFixed(2);
});
}
//
@override
Widget build(BuildContext context) {
return Scaffold(
//상단 앱바를 정의합니다.
appBar: AppBar(
title: Text('Calcurator'),
),
//메인 화면 영역을 정의합니다.
body: Column(
children: <Widget>[
//계산 결과를 표시할 화면입니다.
Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.symmetric(vertical: 24.0, horizontal: 12.0),
child: Text(
output,
style: TextStyle(fontSize: 48.0, fontWeight: FontWeight.bold),
),
),
//화면을 분할 하기위한 구분선을 추가 합니다.
Expanded(
child: Divider(),
),
//계산기 버튼을 구성합니다.
Column(
children: [
Row(
children: [
CalcuratorButton("7", buttonPressed),
CalcuratorButton("8", buttonPressed),
CalcuratorButton("9", buttonPressed),
CalcuratorButton("/", buttonPressed),
],
),
Row(
children: [
CalcuratorButton("4", buttonPressed),
CalcuratorButton("5", buttonPressed),
CalcuratorButton("6", buttonPressed),
CalcuratorButton("x", buttonPressed),
],
),
Row(
children: [
CalcuratorButton("1", buttonPressed),
CalcuratorButton("2", buttonPressed),
CalcuratorButton("3", buttonPressed),
CalcuratorButton("-", buttonPressed),
],
),
Row(
children: [
CalcuratorButton(".", buttonPressed),
CalcuratorButton("0", buttonPressed),
CalcuratorButton("00", buttonPressed),
CalcuratorButton("+", buttonPressed),
],
),
Row(
children: [
CalcuratorButton("CLEAR", buttonPressed),
CalcuratorButton("=", buttonPressed),
],
),
],
),
],
),
);
}
}
6. main.dart 수정
앞서 작성해둔 main.dart파일을 열어 다음과 같이 수정합니다.
import 'package:flutter/material.dart';
import 'calcurator_home.dart'; //수정할 부분
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Calcurator App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: CalcuratorHomePage(), //수정할 부분
);
}
}
7. 앱 실행
모든 코드를 작성하고 오류가 발생하지 않았다면 정상적으로 작동하는지 확인합니다.
실제 디바이스를 사용하거나 VSCode 하단에서 디바이스를 선택합니다.
상단의 실행 버튼을 클릭하거나 , F5 또는 터미널에서 flutter run 명령을 실행하여 입을 실행합니다. 오류가 발생하지 않는다면 아래와 같은 화면처럼 앱이 실행 되어야 합니다.

7. 버튼 크기 및 배경색 변경
calcurator_button.dart의 소스코드를 다음과 같이 변경하여 버튼 크기와 배경색을 조금 더 세련되게 변경할 수 있습니다.
@override
Widget build(BuildContext context) {
return Expanded(
child: Container(
margin: EdgeInsets.all(5.0), // 버튼 사이의 간격을 설정합니다.
child: SizedBox(
width: 70, // 버튼의 너비를 설정합니다.
height: 70, // 버튼의 높이를 설정합니다.
child: OutlinedButton(
onPressed: () => buttonCallback(buttonText),
style: OutlinedButton.styleFrom(
backgroundColor: Colors.blue, // 버튼의 배경색을 설정합니다.
side: BorderSide(
color: Colors.blue, width: 2.0), // 버튼 테두리 색상과 두께를 설정합니다.
shape: RoundedRectangleBorder(
// 버튼 모서리를 둥글게 설정합니다.
borderRadius: BorderRadius.circular(10.0),
),
),
child: Text(
buttonText,
style: TextStyle(
fontSize: 20.0,
color: Colors.white, // 텍스트 색상 변경
),
),
),
),
),
);
}
}

이번 프로젝트에서는 각 클래스를 단계적으로 작성하고 코드가 어떻게 연결되는지 살펴 보았습니다. 이를 통해 앞으로 유지보수성을 높이고, 재사용이 용이한 앱을 작성하는 기초가 되었으면 합니다.
앞으로 다양한 레이아웃과 상태 관리를 배우면서 Flutter 개발 실력을 향상 시킬 수 있는 기회가 되었으면 합니다.
그럼 다음 주 에 새로운 프로젝트로 찾아 오겠습니다.
댓글 남기기