FutureBuilder는 비동기로 데이터를 받을때 결과를 기반으로 UI를 업데이트 하는 위젯이다.
비동기에 대한 이해를 먼저 해야 빌더를 사용할 때 바로적용할 수 있다.
공식 문서는 아래와 같다.
https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
공식 예제는 아래와 같다.
import 'package:flutter/material.dart';
/// Flutter code sample for [FutureBuilder].
void main() => runApp(const FutureBuilderExampleApp());
class FutureBuilderExampleApp extends StatelessWidget {
const FutureBuilderExampleApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: FutureBuilderExample(),
);
}
}
class FutureBuilderExample extends StatefulWidget {
const FutureBuilderExample({super.key});
@override
State<FutureBuilderExample> createState() => _FutureBuilderExampleState();
}
class _FutureBuilderExampleState extends State<FutureBuilderExample> {
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.displayMedium!,
textAlign: TextAlign.center,
child: FutureBuilder<String>(
future: _calculation, // a previously-obtained Future<String> or null
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
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(
width: 60,
height: 60,
child: CircularProgressIndicator(),
),
Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Awaiting result...'),
),
];
}
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: children,
),
);
},
),
);
}
}
실제 예제는 어떠할까
지금 하고 있는 프로젝트에서는 Provider를 사용하고 있다. 예제는 Provider이다.
provider.dart
Future<List<Datas>> readDatas() async {
return Future.delayed(Duration(seconds: 2), () async {
return data = await DBHelper.instance.getData();
});
}
view.dart
SafeArea(
child: Consumer<provider>(
builder: (context, provider, child) {
return FutureBuilder<List<Data>>(
future: provider.readDatas(),
builder: (context, snapshot) {
if (snapshot.hasData) {
final List<Datas>? datas = snapshot.data;
if (datas != null) {
return ListView.builder(
itemCount: provider.datas.length,
itemBuilder: (context, index) {
return Container(
child: Text(datas[index]),
)
},
);
} else if (snapshot.hasError) {
return Center(
child:
Text("Sorry, there is a problem"),
);
}
}
return Center(
child: CircularProgressIndicator(),
);
},
);
},
),
),
);
아무튼 이렇게 빌더를 사용하면 된다.
버전에 따라 사용하는 방법이 좀 다르니 공식문서를 참조하면 된다.
그리고 빌더와 리스트뷰를 사용하는건 가끔 퍼포먼스가 안좋다는 글을 봤는데
일단 그런 생각은 앱 완성한 후에 해야겠다.
조만간 비동기글도 가져올께요.
'develop > Flutter' 카테고리의 다른 글
Flutter Tts 사일런트 모드일때 사운드 재생 안됨 해결하기 iOS AudioCategory 구분하기 (0) | 2023.08.15 |
---|---|
VSCode MARK 하이라이팅 하기 키워드 커스텀 Keyword [Xcode 처럼] (0) | 2023.08.09 |
Flutter 화면 방향 Orientation에 따라 레이아웃 변경 Landscape Portrait 뜻 (0) | 2023.07.28 |
[flutter] SKAdNetwork 앱 광고 추적 허용 요청하기 in iOS (0) | 2023.05.19 |
[Flutter] 효과음 재생 시 백그라운드 뮤직 정지 되는 문제 야매로 해결하기 (다른 앱의 소리와 효과음이 동시에 재생되게 하기) (0) | 2023.05.17 |