Mobile/Flutter

Flutter(플러터) - Stream을 이용한 카운터 앱

풍중현 2020. 2. 16. 17:03

Flutter Counter App은 플러터 프로젝트를 생성하면 기본적으로 생성이 되는 앱이다.

 

이번엔 dart 언어에서 비동기 프로그래밍을 지원해주는 async 라이브러리를 활용하여

 

Stream을 활용한 카운터 앱을 만들어 보았다.

 

  • lib/counter_page.dart 파일을 만든다.
  • dart:async를 임포트한다.
  • Stateful Widget을 만든다. 
  • Stream을 사용하여 구현한다.

main.dart

import 'package:flutter/material.dart';
import 'package:flutter_infinite_scroll_bloc/counter_page.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: CounterPage()
    );
  }
}

counter_page.dart

import 'dart:async';
import 'package:flutter/material.dart';

class CounterPage extends StatefulWidget {
  @override
  _CounterPageState createState() => _CounterPageState();
}

class _CounterPageState extends State<CounterPage> {
  /// 상태: 카운터
  int _counter = 0;

  // 정수형의 데이터를 제어하는 스트림
  final StreamController<int> _streamController = StreamController<int>();


  @override
  void dispose() {
    // stream도 닫아줘야 한다.
    _streamController.close();
    super.dispose();
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('스트림을 이용한 카운터 앱'),),
      body: Center(
        // StreamBuilder 리스너를 등록할 수 있다.
        child: StreamBuilder<int>(
          // 스트림을 등록한다. 보통 listening, subscribe한다고 한다.
          stream: _streamController.stream,

          // 초기 데이터
          initialData: _counter,

          // Builder 패턴을 사용하여 이곳에서 위젯을 정의한다.
          builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
            return Text('카운터: ${snapshot.data}');
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.add),
        onPressed: () {
          /// 버튼이 눌리면 카운터를 1씩 증가시킨다.
          /// sink는 스트림에서 데이터를 보내는 입구다.
          _streamController.sink.add(++_counter);
        },
      ),
    );
  }
}