일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- GitHub
- Git
- 데스크셋업
- datetime
- error
- 데스크테리어
- Flutter
- Android
- list
- TextField
- visualstudiocode
- swift
- 내돈내산
- 라이언
- 간단리뷰
- 카카오
- listview
- xcode
- wrap
- M1
- VSCode
- 춘식
- AppleSilicon
- AppBar
- ios
- sqflite
- react
- GetX
- database
- 플러터
- Today
- Total
welcome to my blog
[Flutter] SmartRefresher 정리 본문
리스트뷰를 하단으로 스크롤하면서 데이터를 그때그때 받아 올 때 사용할 만한 라이브러리
사용 라이브러리
pull_to_refresh: ^2.0.0
dio: ^4.0.4
사용 플러그인
FlutterJsonBeanFactory 4.3.2
임시로 데이터가 필요하기때문에 instantwebtools.net의 fake rest api 를 이용하여 테스트 해보겠다.
https://instantwebtools.net/fake-rest-api
Fake Rest API | Instant Web Tools
When Data Getting Reset? As of now, we are going to open this API to the world through the public internet. So people could use this API whenever they need wherever they need. So data will be junked and deleted by the time, So we are running the data reset
instantwebtools.net
FAKE API -> Available Endpoints
사용한 url :
https://api.instantwebtools.net/v1/passenger?page=0&size=10
url을 입력하면 해당 결과값을 json 형태로 보여줌
https://jsonformatter.curiousconcept.com/#
JSON Formatter & Validator
Format and validate JSON data so that it can easily be read by human beings.
jsonformatter.curiousconcept.com
본격 시작
데이터 가져오기
다음 url을 https://jsonformatter.curiousconcept.com/# 의 JSON Data/URL에 넣고 결과값을 받는다.
https://api.instantwebtools.net/v1/passenger?page=0&size=10
결과값이 아래 나온다.
생성할 클래스 이름을 작성해주고 아래에는 결과값으로 반환된 값을 넣어준다.
passenger_model_entity.dart 파일(model)과 generated 폴더 등 자동으로 생성됨
stateful widget을 하나 만든다 (예제에서는 TestHomePage)
변수 정의
/// 현재 페이지 정보
int currentPage = 1;
/// 전체 페이지 정보
late int totalPages;
/// 수신 데이터 리스트
List<PassengerModelData>? passengers = [];
/// Refresher controller 생성
/// initialRefresh : SmartRefresher가 초기화되면 즉시 requestRefresh를 호출합니다.
final RefreshController refreshController =
RefreshController(initialRefresh: true);
scaffold의 body에 SmartRefresher 추가
SmartRefresher 추가
SmartRefresher의 controller에 refreshController 연결. child에는 ListView 추가
onRefresh, onLoading 에 다음코드 추가
onRefresh : 콜백이 발생하면 [RefreshController]를 사용하여 새로 고침 상태를 종료해야 합니다. 그렇지 않으면 새로 고침 상태를 유지합니다.
onLoading : 콜백이 발생하면 [RefreshController]를 사용하여 로드 상태를 종료해야 합니다. 그렇지 않으면 로드 상태를 유지합니다.
onRefresh: () async {
final result = await getPassengerData(isRefresh: true);
if (result) {
refreshController.refreshCompleted();
} else {
refreshController.refreshFailed();
}
},
onLoading: () async {
final result = await getPassengerData();
if (result) {
refreshController.loadComplete();
} else {
refreshController.loadFailed();
}
},
getPassengerData 함수 정의
Future<bool> getPassengerData({bool isRefresh = false}) async {
if (isRefresh) {
/// 리스트뷰 상단에서 아래쪽으로 내리는 동작을 하면 refresh true
/// currentpage를 1로 해서 목록을 초기화 시킴
currentPage = 1;
} else {
/// 전체 페이지보다 현재 페이지가 크면 => 마지막 페이지면 더이상 로드 할 게 없음
if (currentPage >= totalPages) {
refreshController.loadNoData();
return false;
}
}
/// size 에 넣은 값 만큼 개수를 가져온다.
String url =
"https://api.instantwebtools.net/v1/passenger?page=$currentPage&size=20";
/// Dio 라이브러리를 이용하여 url 의 응답을 받아온다.
final response = await Dio().get(url);
/// 정상 응답일 경우
if (response.statusCode == 200) {
PassengerModelEntity tempIteaam = PassengerModelEntity();
/// result에 파싱한 데이터를 넣는다.
final result = $PassengerModelEntityFromJson(response.data);
/// 새로고침 인 경우 passengers 리스트변수를 해당 값으로 초기화
if (isRefresh) {
passengers = result.data;
} else {
/// 새로고침이 아닌경우(최 하단에서 올리는 동작인 경우) passengers변수에 데이터 이어붙임
passengers!.addAll(result.data!);
}
/// 현재 페이지 +1
currentPage++;
totalPages = result.totalPages!;
/// 수신된 데이터 확인
print(response.data);
/// 변수 업데이트
setState(() {});
return true;
} else {
return false;
}
}
수신된 response 데이터를 이용하여 ListView UI에 자유롭게 표현해주면 됨
[전체 코드]
/// test_future.dart
import 'package:abcworks/generated/json/passenger_model_entity.g.dart';
import 'package:abcworks/screens/main/my/passenger_model_entity.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
Future<void> main() async {
runApp(MaterialApp(
title: "test title",
home: TestHomePage(),
));
}
class TestHomePage extends StatefulWidget {
const TestHomePage({Key? key}) : super(key: key);
@override
_TestHomePageState createState() => _TestHomePageState();
}
class _TestHomePageState extends State<TestHomePage> {
int currentPage = 1;
late int totalPages;
List<PassengerModelData>? passengers = [];
final RefreshController refreshController =
RefreshController(initialRefresh: true);
Future<bool> getPassengerData({bool isRefresh = false}) async {
if (isRefresh) {
currentPage = 1;
} else {
if (currentPage >= totalPages) {
refreshController.loadNoData();
return false;
}
}
String url =
"https://api.instantwebtools.net/v1/passenger?page=$currentPage&size=20";
final response = await Dio().get(url);
if (response.statusCode == 200) {
PassengerModelEntity tempIteaam = PassengerModelEntity();
final result = $PassengerModelEntityFromJson(response.data);
if (isRefresh) {
passengers = result.data;
} else {
passengers!.addAll(result.data!);
}
currentPage++;
totalPages = result.totalPages!;
print(response.data);
setState(() {});
return true;
} else {
return false;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("test future builder"),
),
body: SmartRefresher(
controller: refreshController,
enablePullUp: true,
onRefresh: () async {
final result = await getPassengerData(isRefresh: true);
if (result) {
refreshController.refreshCompleted();
} else {
refreshController.refreshFailed();
}
},
onLoading: () async {
final result = await getPassengerData();
if (result) {
refreshController.loadComplete();
} else {
refreshController.loadFailed();
}
},
child: ListView.separated(
itemBuilder: (context, index) {
final passenger = passengers![index];
return ListTile(
title: Text(passenger.name!),
subtitle: Column(
children: [
Image(image: NetworkImage(passenger.airline![0].logo!), height: 30, width: 30, ),
Text(passenger.airline![0].country!)
],
),
trailing: Text(index.toString()),
);
},
separatorBuilder: (context, index) => Divider(),
itemCount: passengers!.length),
),
);
}
}
/// passenger_model_entity.dart
import 'dart:convert';
import 'package:abcworks/generated/json/base/json_field.dart';
import 'package:abcworks/generated/json/passenger_model_entity.g.dart';
@JsonSerializable()
class PassengerModelEntity {
int? totalPassengers;
int? totalPages;
List<PassengerModelData>? data;
PassengerModelEntity();
factory PassengerModelEntity.fromJson(Map<String, dynamic> json) => $PassengerModelEntityFromJson(json);
Map<String, dynamic> toJson() => $PassengerModelEntityToJson(this);
@override
String toString() {
return jsonEncode(this);
}
}
@JsonSerializable()
class PassengerModelData {
@JSONField(name: "_id")
String? sId;
String? name;
int? trips;
List<PassengerModelDataAirline>? airline;
@JSONField(name: "__v")
int? iV;
PassengerModelData();
factory PassengerModelData.fromJson(Map<String, dynamic> json) => $PassengerModelDataFromJson(json);
Map<String, dynamic> toJson() => $PassengerModelDataToJson(this);
@override
String toString() {
return jsonEncode(this);
}
}
@JsonSerializable()
class PassengerModelDataAirline {
int? id;
String? name;
String? country;
String? logo;
String? slogan;
@JSONField(name: "head_quaters")
String? headQuaters;
String? website;
String? established;
PassengerModelDataAirline();
factory PassengerModelDataAirline.fromJson(Map<String, dynamic> json) => $PassengerModelDataAirlineFromJson(json);
Map<String, dynamic> toJson() => $PassengerModelDataAirlineToJson(this);
@override
String toString() {
return jsonEncode(this);
}
}
https://pub.dev/packages/pull_to_refresh
pull_to_refresh | Flutter Package
a widget provided to the flutter scroll component drop-down refresh and pull up load.
pub.dev
'Flutter' 카테고리의 다른 글
[Flutter] 아이폰 빌드 / Developer Mode Disabled (0) | 2023.02.09 |
---|---|
[Flutter] 윤년계산하기 - dart (0) | 2022.03.22 |
[Flutter] RxMap 사용 (0) | 2022.01.20 |
[Flutter] Wrap, Chip, FlowLayout (0) | 2022.01.11 |
[Flutter ]textbuttonTheme (0) | 2022.01.11 |