Future 란?
지금은 없지만 미래에 작업이 수행되어 결과를 나타낼 것이라는 상태를 나타냄.
future 는 비동기 작업의 결과를 나타내며 미완료(데이터 value를 생성하기 전) 또는 완료(데이터 value 생성)의 두 가지 상태를 가질 수 있다.
미완료 : 비동기 함수를 호출하면 데이터 value 가 생성되기 전인 완료되지 않은 미래가 반환된다. future 는 비동기 함수의 작업이 완료되거나 오류가 발생하기를 기다리고 있다.
완료 : 비동기 작업이 성공하면 future 를 데이터 value 로 반환한다.
작성한 파일 목록 입니다.
1. pubspec.yaml
2. HttpService.dart
3. FutureScrollPage.dart
1. pubspec.yaml
http 통신을 사용하려면 일단 pubspec.yaml 파일에 dependencies 를 추가해줘야 하는데요!
http | Dart Package
A composable, multi-platform, Future-based API for HTTP requests.
pub.dev
여기서 http 의 버전을 확인하여 추가해줍니다!
flutter: 와 같은 라인에 http: 를 추가해주어야해요~~!
http: ^0.13.3
=============== pubspec.yaml ===============
...
dependencies:
flutter:
sdk: flutter
http: ^0.13.3
...
그런데 버전을 명시하지 않고 그냥
http:
이렇게만 입력하면 현재 최신버전을 사용하겠다는 것이라고 하네요!
=============== pubspec.yaml ===============
...
dependencies:
flutter:
sdk: flutter
http:
...
2. HttpService.dart
http 통신을 통해 데이터를 가져오는 부분입니다.
'package:http/http.dart' as http 를 import 해서 yaml 파일에 dependencies 추가한 http 를 사용하도록 해줍니다.
그리고 json 형태로 변환하기 위해 'dart:convert' 를 import 하여 json.decode() 를 사용하였습니다.
import 'dart:convert';
import 'package:flutter_application_1/model/BearItem.dart';
import 'package:http/http.dart' as http;
class HttpService {
Future<http.Response> fetch() async {
String url = 'http://-----:8080/MyTestProj/index.jsp';
Uri uri = Uri.parse(url);
return http.get(uri);
}
Future<BearList> fetchBear() async {
String url = 'http://-----:8080/MyTestProj/index.jsp';
Uri uri = Uri.parse(url);
var response = await http.get(uri);
var statusCode = response.statusCode;
var headers = response.headers;
var body = json.decode(response.body);
print('[$runtimeType] fetchBear - statusCode : $statusCode');
print('[$runtimeType] fetchBear - headers : $headers');
print('[$runtimeType] fetchBear - body : $body');
if (response.statusCode == 200) {
return BearList.fromJson(body);
} else {
throw Exception(' Failed to load Bear ');
}
}
}
이 부분은 아래의 링크를 참고하여 작성하였습니다.
https://flutter.dev/docs/cookbook/networking/fetch-data
Fetch data from the internet
How to fetch data over the internet using the http package.
flutter.dev
3. FutureScrollPage.dart
기존에 dart 파일 상단에 하드코딩으로 이용했던 json 데이터를 http 통신을 통해 가져오겠습니다.
그리고 FloatingActionButton 을 통해 제일 상단/하단으로 강제 스크롤하는 코드를 사용하였습니다.
FutureBuilder 사용
FutureBuilder<BearList>( //FutureBuilder 를 사용하여 데이터 가져오기
future: HttpService().fetchBear(), //http 통신하는 메소드
builder: (context, snapshot) {
if(snapshot.hasData) { //작업이 완료 시 - snapshot 을 통해 데이터 반환
return bodyWidget(snapshot.data!);
} else { //작업이 미완료시 - ProgressIndicator 위젯 표시
return Center(
child: CircularProgressIndicator(),
);
}
},
),
FutureBuilder 는 위의 형태를 사용합니다.
scrollController 를 사용한 강제 스크롤
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) { //이 프레임에서 가장 나중에 실행되겠다
_scrollController.animateTo(
_scrollController.position.minScrollExtent, //minScrollExtent:제일 상단, maxScrollExtent:제일 하단
duration: Duration(milliseconds: 200),
curve: Curves.easeInOut,
);
});
이 형태를 사용합니다.
FutureScrollPage.dart 전체소스
import 'package:flutter/material.dart';
import 'HttpService.dart';
import 'model/BearItem.dart';
class FutureScrollPage extends StatefulWidget {
const FutureScrollPage({
Key? key,
}) : super(key: key);
@override
_FutureScrollPageState createState() => _FutureScrollPageState();
}
class _FutureScrollPageState extends State<FutureScrollPage> {
late ScrollController _scrollController = ScrollController();
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('FutureScrollPage'),
),
floatingActionButton: Container(
alignment: Alignment.bottomCenter,
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end,
children: [
//FloatingActionButton 1 : 가장 위로 강제 스크롤
FloatingActionButton(
onPressed: () {
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
_scrollController.animateTo(
_scrollController.position.minScrollExtent,
duration: Duration(milliseconds: 200),
curve: Curves.easeInOut,
);
});
},
child: Icon(Icons.arrow_upward),
),
//FloatingActionButton 2 : 가장 아래로 강제 스크롤
FloatingActionButton(
onPressed: () {
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
_scrollController.animateTo(
_scrollController.position.maxScrollExtent,
duration: Duration(milliseconds: 200),
curve: Curves.easeInOut,
);
});
},
child: Icon(Icons.arrow_downward),
),
],
),
),
body: FutureBuilder<BearList>( //FutureBuilder 를 사용하여 데이터 가져오기
future: HttpService().fetchBear(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return bodyWidget(snapshot.data!);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
),
),
);
}
Widget bodyWidget(BearList bearList) {
return Container(
child: ListView.separated(
controller: _scrollController,
separatorBuilder: (BuildContext context, int index) => const Divider(
color: Colors.grey,
height: 4,
), //separatorBuilder : item과 item 사이에 그려질 위젯 (개수는 itemCount -1 이 된다)
itemCount: bearList.list!.length, //리스트의 개수
itemBuilder: (BuildContext context, int index) {
//리스트의 반목문 항목 형성
return Container(
height: 80,
decoration: BoxDecoration(
color: Colors.pink[index * 100],
),
child: Row(
children: [
Container(
width: 50,
alignment: Alignment.center,
child: Text(
'$index',
style: TextStyle(
fontSize: 20,
),
),
),
Image.asset(
bearList.list!.elementAt(index).image!,
),
Expanded(
child: Container(
alignment: Alignment.center,
child: Text(
bearList.list!.elementAt(index).name!,
style: TextStyle(
fontSize: 20,
),
),
),
),
],
),
);
},
),
);
}
}
결과화면
감사합니다.
![](https://t1.daumcdn.net/keditor/emoticon/friends1/large/003.gif)
'📘 Flutter' 카테고리의 다른 글
[Flutter] 다양한 위젯(Widget) 사용하기 - Dialog, DatePicker, TimePicker, SnackBar, GestureDetector, InkWell (0) | 2021.07.17 |
---|---|
[Flutter] TextField 사용하기 (3) | 2021.07.07 |
[Flutter] 탭바(TabBar) 사용하기 (0) | 2021.07.06 |
[Flutter] CarouselSlider (2) | 2021.06.27 |
[Flutter] 카드(Card) 위젯 사용하기 (0) | 2021.06.27 |