Flutter of the week란?
공식 유튜브 채널에서 주 1회 Flutter의 다양한 기능, 팁, 패키지등의 사용 사례에 대한 간결하고 유익한 정보를 제공하는 영상시리즈
바로가기
FutureBuilder 란?
A widget that builds itself based on the latest snapshot of interaction with a Future.
- (미래에)어떤 작업이 끝날 때까지 기다렸다가, 그 작업의 최신 결과를 기반(스냅샷을 통해)으로 자동으로 화면을 업데이트하는 기능을 갖춘 위젯
FutureBuilder는 플러터에서 비동기 작업을 수행하고 해당 작업의 결과에 따라 UI를 업데이트하는 데 사용되는 위젯입니다. 주로 네트워크 호출, 데이터 로딩 또는 유저의 입력에 따라 데이터를 업데이트해야 될 경우 사용됩니다.
*비동기 : 프로그램이 작업의 완료를 기다리지 않고, 동시에 여러 작업을 수행할 수 있는 프로그래밍 방식
FutureBuilder 위젯 사용법
FutureBuilder(
future: fetchData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
} else if (snapshot.hasError) {
return Text("데이터 가져오기에 실패했습니다.");
} else {
List<String> data = snapshot.data;
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
return Text(data[index]);
},
);
}
},
)
- future 속성에는 Future타입의 class가 들어가며 해당 클래스의 상태가 snapshot안에 담기게 됩니다.
- snapshot
- snapshot.hasData : 데이터 여부를 확인 하는 bool값입니다 현재 데이터가 있다면 true가 반환됩니다.
- snapshot.hasError : Error 여부를 확인하는 bool값입니다.
- snapshot.data : snapshot의 데이터를 가져옵니다. 해당 데이터로 ui에 적용하거나 비즈니스로직을 처리합니다.
- snapshot.connectionState
- connectionState 에는 연결 상태값이 들어오게 됩니다.
- ConnectionState.waiting(기다리는중), ConnectionState.done(완료), ConnectionState.none(연결 없음) 등이 들어오게 됩니다.
사용예제
FutureBuilder 가상의 서버에서 로그인 인증을 하는 로직으로 구성했습니다.
1.유저가 입력한 값이 저장된 id값과 일치하면 true, 일치하지 않으면 false를 돌려주는 Future함수를 만듭니다.
Future<bool> login() async {
//로그인 정보 확인
await Future.delayed(const Duration(seconds: 2));
if (userId == 'abc') {
return true;
}
return false;
}
2. FutureBuilder를 생성하고 1.에서 생성한 Future함수를 future속성에 넣어줍니다.
snapshot.data가 false일경우 ui에 '아이디를 확인해주세요'라는 안내문구를 보여줍니다.
FutureBuilder(
future: login(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
} else {
if (snapshot.hasError) {
return Text('error :${snapshot.error}');
} else {
if (snapshot.data! == true) {
return Text('로그인 성공');
}
return Text('아이디를 확인해주세요');
}
}
},
),
3. 마지막으로 버튼을 눌렀을때 유저가 현재 입력한 값과 저장된 ID값이 같다면 로그인 성공 페이지로 넘겨주는 함수를 생성합니다.
void handleLogin() async {
setState(() {
userId = controller.text;
});
bool loginResult = await login();
if (loginResult) {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => LoginScreen()));
}
}
전체코드
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_of_the_week/screen/login.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
TextEditingController controller = TextEditingController();
String userId = '';
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.orange,
title: Text(
'FutureBuilder로 로그인 구현하기',
),
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
'ID',
style: TextStyle(fontSize: 32),
),
TextFormField(
controller: controller,
decoration: const InputDecoration(
border: OutlineInputBorder(),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.orange)),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FutureBuilder(
future: login(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
} else {
if (snapshot.hasError) {
return Text('error :${snapshot.error}');
} else {
if (snapshot.data! == true) {
return Text('로그인 성공');
}
return Text('아이디를 확인해주세요');
}
}
},
),
],
),
ElevatedButton(
onPressed: handleLogin,
child: Text('로그인'))
],
),
),
);
}
void handleLogin() async {
setState(() {
userId = controller.text;
});
bool loginResult = await login();
if (loginResult) {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => LoginScreen()));
} else {}
}
Future<bool> login() async {
//로그인 정보 확인
await Future.delayed(const Duration(seconds: 2));
if (userId == 'abc') {
return true;
}
return false;
}
}
'Flutter Widget of the Week 톺아보기' 카테고리의 다른 글
05. Opacity in Flutter [Flutter Widget of the Week]톺아보기 (0) | 2024.01.16 |
---|---|
04. AnimatedContainer in Flutter [Flutter Widget of the Week]톺아보기 (0) | 2024.01.15 |
03. Wrap in Flutter [Flutter Widget of the Week 톺아보기 (1) | 2024.01.10 |
02. Expanded in Flutter [Flutter Widget of the Week 톺아보기] (2) | 2024.01.08 |
01. SafeArea in Flutter [Flutter Widget of the Week 톺아보기] (0) | 2024.01.07 |