Plog
Flutter 카운터 앱 Steam -> Bloc 본문
main.dart
import 'package:flutter/material.dart';
import 'package:flutter_infinite_scroll_bloc/counter_page.dart';
import 'package:flutter_infinite_scroll_bloc/increment_bloc.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: BlocProvider<IncrementBloc>(
bloc: IncrementBloc(),
child: CounterPage(),
)
);
}
}
counter_page.dart
import 'package:flutter/material.dart';
import 'package:flutter_infinite_scroll_bloc/increment_bloc.dart';
class CounterPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final IncrementBloc bloc = BlocProvider.of<IncrementBloc>(context);
return Scaffold(
appBar: AppBar(title: Text('Bloc Counter App')),
body: Center(
child: StreamBuilder<int>(
stream: bloc.outCounter,
initialData: 0,
builder: (BuildContext context, AsyncSnapshot snapshot) {
return Text('${snapshot.hasData ? snapshot.data : 0}');
},
),
),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () {
bloc.incrementCounter.add(null);
}
),
);
}
}
increment_bloc.dart
import 'dart:async';
import 'package:flutter/cupertino.dart';
// Bloc 클래스
class IncrementBloc implements BlocBase {
int _counter;
// 카운터 출력을 위한 스트림을 제어하는 controller, sink, stream
StreamController<int> _counterController = StreamController<int>();
StreamSink<int> get _inAdd => _counterController.sink;
Stream<int> get outCounter => _counterController.stream;
// floating action button 이벤트를 제어하는 스트림 컨트롤러
// floating action button을 누르면 _counterContoller.sink로
// 1증가시킨 cohnter를 전달한다.
StreamController _actionController = StreamController();
StreamSink get incrementCounter => _actionController.sink;
IncrementBloc() {
_counter = 0;
_actionController.stream.listen(_handleLogic);
}
@override
void dispose() {
_actionController.close();
_counterController.close();
}
void _handleLogic(data) {
_counter = _counter + 1;
_inAdd.add(_counter);
}
}
// Bloc 구현을 위한 추상 클래스
abstract class BlocBase {
void dispose();
}
/// BlocProvider
/// 하위 위젯에서도 Bloc에 접근해줄 수 있게한다.
/// build(BuildContext context) 안에서
/// final IncrementBloc bloc = BlocProvider.of<IncrementBloc>(context);
class BlocProvider<T extends BlocBase> extends StatefulWidget {
BlocProvider({
Key key,
@required this.child,
@required this.bloc,
}) : super(key: key);
final T bloc;
final Widget child;
@override
State<StatefulWidget> createState() => _BlocProviderState();
static T of<T extends BlocBase>(BuildContext context) {
BlocProvider<T> provider = context.findAncestorWidgetOfExactType<BlocProvider<T>>();
return provider.bloc;
}
}
class _BlocProviderState<T> extends State<BlocProvider<BlocBase>> {
@override
void dispose() {
// TODO: implement dispose
widget.bloc.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return widget.child;
}
}
'Mobile > Flutter' 카테고리의 다른 글
flutter_bloc 패키지를 이용한 카운터 앱 (0) | 2020.02.16 |
---|---|
Flutter - rxdart streams (0) | 2020.02.16 |
Flutter(플러터) - Stream을 이용한 카운터 앱 (0) | 2020.02.16 |