[flutter] 스택드 위젯을 사용하여 타이머 앱 만들기

이번에는 Flutter의 스택드(Stacked) 위젯을 사용하여 간단한 타이머(timer) 앱을 만들어보겠습니다. 스택드 위젯은 다른 위젯을 겹쳐서 배치할 때 유용하며, 타이머 앱에서는 타이머 카운트를 화면 상에 중앙에 표시하고 버튼을 통해 시작, 일시정지, 초기화 기능을 구현할 것입니다.

프로젝트 설정

먼저, Flutter 프로젝트를 생성하고 의존성에 flutter_bloc 패키지를 추가합니다.

flutter create timer_app
cd timer_app
flutter pub add flutter_bloc

스택드 위젯과 BLoC 패턴

스택드 위젯은 Flutter에서 여러 위젯을 겹쳐서 표시할 때 사용됩니다. 이를 통해 화면의 레이아웃을 구성할 수 있습니다. BLoC 패턴은 비즈니스 로직을 UI에서 분리하는 데 도움을 주는 패턴으로, 타이머 앱에서는 타이머 상태와 사용자 입력을 관리하기 위해 사용됩니다.

타이머 앱 구현

먼저, main.dart 파일에서 앱 진입점을 구성합니다.

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'timer_bloc.dart';
import 'timer_page.dart';

void main() {
  runApp(TimerApp());
}

class TimerApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Timer App',
      home: BlocProvider(
        create: (context) => TimerBloc(),
        child: TimerPage(),
      ),
    );
  }
}

다음으로, timer_bloc.dart 파일에서 BLoC를 정의합니다.

import 'package:flutter_bloc/flutter_bloc.dart';

enum TimerEvent { start, pause, reset }

class TimerBloc extends Bloc<TimerEvent, int> {
  TimerBloc() : super(0);

  @override
  Stream<int> mapEventToState(TimerEvent event) async* {
    switch (event) {
      case TimerEvent.start:
        while (true) {
          await Future.delayed(Duration(seconds: 1));
          yield state + 1;
        }
        break;
      case TimerEvent.pause:
        // Add pause logic
        break;
      case TimerEvent.reset:
        yield 0;
        break;
    }
  }
}

마지막으로, timer_page.dart 파일에서 타이머 화면을 구성합니다.

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'timer_bloc.dart';

class TimerPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Timer App'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            BlocBuilder<TimerBloc, int>(
              builder: (context, state) {
                return Text(
                  '$state seconds',
                  style: TextStyle(fontSize: 40),
                );
              },
            ),
            SizedBox(height: 20),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: <Widget>[
                FloatingActionButton(
                  onPressed: () {
                    context.read<TimerBloc>().add(TimerEvent.start);
                  },
                  child: Icon(Icons.play_arrow),
                ),
                FloatingActionButton(
                  onPressed: () {
                    context.read<TimerBloc>().add(TimerEvent.pause);
                  },
                  child: Icon(Icons.pause),
                ),
                FloatingActionButton(
                  onPressed: () {
                    context.read<TimerBloc>().add(TimerEvent.reset);
                  },
                  child: Icon(Icons.stop),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

마치며

위 예시에서는 Flutter의 스택드(Stacked) 위젯과 BLoC 패턴을 사용하여 간단한 타이머 앱을 만드는 방법을 살펴보았습니다. 이를 통해 Flutter에서 상태 관리와 화면 구성을 함께 다루는 방법에 대해 이해할 수 있습니다. 또한, BLoC를 통해 비즈니스 로직과 UI를 분리함으로써 코드의 유지보수성을 높일 수 있습니다.

참고 문헌:
Flutter 공식 문서
Flutter Bloc 패키지 공식 문서

이상으로 타이머 앱 개발에 대한 기초적인 내용을 마치도록 하겠습니다. 감사합니다!