-
[Flutter]플러터 Futurebuilder / Streambuilder란??플러터 Flutter 2021. 5. 30. 17:43반응형
아직까지 나도 제대로 적용한적은 없고 그냥 구글링하면서 학습겸 정리하였다.
- FutureBuilder 공식문서 바로가기
앨범에서 이미지 가져오기, 배터리 표시, 파일 가져오기, http요청등 일회성 응답에 사용
- StreamBuilder 공식문서 바로가기
위치 업데이트, 음악 재생, 스톱워치 일부 데이터를 여러번 가져올때 사용
둘다 코드를 읽고 error 나 data 받는다.- FutureBuilder 샘플코드
코드를 복사해서 실행하면 2초 로드후 데이터를 가져왔다는 성공 메시지를 띄우는 예제이다.※FutureBuilder는 StatefulWidget의 자식클래스이다.
1. FutureBuilder
import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); /// This is the main application widget. class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); static const String _title = 'Flutter Code Sample'; @override Widget build(BuildContext context) { return const MaterialApp( title: _title, home: MyStatefulWidget(), ); } } /// This is the stateful widget that the main application instantiates. class MyStatefulWidget extends StatefulWidget { const MyStatefulWidget({Key? key}) : super(key: key); @override State<MyStatefulWidget> createState() => _MyStatefulWidgetState(); } /// This is the private State class that goes with MyStatefulWidget. class _MyStatefulWidgetState extends State<MyStatefulWidget> { final Future<String> _calculation = Future<String>.delayed( const Duration(seconds: 2), () => 'Data Loaded', ); @override Widget build(BuildContext context) { return DefaultTextStyle( style: Theme.of(context).textTheme.headline2!, textAlign: TextAlign.center, child: FutureBuilder<String>( future: _calculation, // a previously-obtained Future<String> or null builder: (BuildContext context, AsyncSnapshot<String> snapshot) { //data가 있으면 snapshot.data List<Widget> children; if (snapshot.hasData) { children = <Widget>[ const Icon( Icons.check_circle_outline, color: Colors.green, size: 60, ), Padding( padding: const EdgeInsets.only(top: 16), child: Text('Result: ${snapshot.data}'), ) ]; } else if (snapshot.hasError) { children = <Widget>[ const Icon( Icons.error_outline, color: Colors.red, size: 60, ), Padding( padding: const EdgeInsets.only(top: 16), child: Text('Error: ${snapshot.error}'), ) ]; } else { children = const <Widget>[ SizedBox( child: CircularProgressIndicator(), width: 60, height: 60, ), Padding( padding: EdgeInsets.only(top: 16), child: Text('Awaiting result...'), ) ]; } return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: children, ), ); }, ), ); } }
- 간단한 예제
class Sample extends StatelessWidget { @override Widget build(BuildContext context) { return FutureBuilder<SharedPreferences>( future: SharedPreference.getInstance(), builder: (BuildContext context, AsyncSnapshot<SharedPreferences> snapshot) { String result; if (snapshot.hasData == false) { result = "Loading..."; } else if (snapshot.data.getString("sessionKey")) { result = "You has session key."; } else { result = "You has not session key."; } return Center( child: Text(result); ); } ) } }
Async/await 키워드를 사용하여 비동기를 처리하는 것을 직관적으로 코드를 작성할 수 있다. FutureBuilder<T>에서 <T>는 비동기로 처리할 타입이 된다. builder에서는 AsyncSnapshot<T>인자를 통해서 <T>에 넘겨진 타입이 비동기로 처리되는 동안의 상태를 처리한다.
2. StreamBuilder
Stream?
스트림은 데이터가 들어오고 나가는 통로다.데이터가 변하는 걸 보고 있다가 그에 맞춰 적절한 처리.. 필터링(where)이나 수정(map), 버퍼링(take)같은 일을 한다.
StreamController?
스트림 컨트롤러는 여러 리스너(구독&상태)을 관리한다.
- 아래의 예제는 값이 추가 될때마다 출력하는 소스이다.
void main() { StreamController ctrl = StreamController(); ctrl.stream.listen((data) { print(data); }); ctrl.add(1); ctrl.add("Hello Stream"); ctrl.add({"first": 10, "tow": "20"}); ctrl.close(); }
플러터에서는 스트림 빌더(StreamBuilder)를 써서 스트림 처리를 한다.
스트림 빌더를 쓰면 setState() 를 쓰지 않고도 UI를 업데이트 할 수 있다.
또 항상 스트림의 최신값을 가져오니, 최신값을 확인할 필요가 없다.- StreamBuilder 예제
import 'dart:async'; import 'package:flutter/material.dart'; void main() => runApp(new MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Flutter Demo', theme: new ThemeData( primarySwatch: Colors.blue, ), home: new MyHomePage(), ); } } class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => new _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { int _counter = 0; StreamController<int> _events; @override initState() { super.initState(); _events = new StreamController<int>(); _events.add(0); } void _incrementCounter() { _counter++; _events.add(_counter); } @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text("StreamBuilder test"), ), body: new Center( child: new Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ new Text( 'You have pushed the button this many times:', ), StreamBuilder( stream: _events.stream, builder: (BuildContext context, snapshot) { return new Text( snapshot.data.toString(), style: Theme.of(context).textTheme.display1, ); }, ), ], ), ), floatingActionButton: new FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: new Icon(Icons.add), ), // This trailing comma makes auto-formatting nicer for build methods. ); } }
본문의 참조
https://zerodice0.tistory.com/225
https://ahang.tistory.com/16
https://eunjin3786.tistory.com/272반응형'플러터 Flutter' 카테고리의 다른 글
[Flutter] 플러터 코드에서 dispose() 메소드를 사용 하는이유?? (0) 2021.06.13 [Flutter/Drat]다트 유용한 메소드 Method 함수 Function 정리~ (0) 2021.06.12 [Flutter] 플러터 Text 텍스트 위젯(TextSpan, RichText Text.rich ) (0) 2021.05.02 [Flutter] Image 이미지 box.fit 옵션 정리 (1) 2021.04.25 [Flutter] 플러터 async*/ yield / yield* 키워드 (0) 2021.04.25