플러터에서 무한스크롤을 구현하는 다음의 패키지가 있는데, 그 안의 예제가 좀 복잡해서 단순화 해 봄.
예제안의 api URL도 동작안하길래 다른 곳으로 바꾸고, 또 혹시 몰라서 첨부파일에 그 json 받은 파일도 넣어 놨음.;;;;
https://github.com/EdsonBueno/infinite_scroll_pagination/
https://pub.dev/packages/infinite_scroll_pagination
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:http/http.dart' as http;
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) => MaterialApp(
title: 'Infinite Scroll Pagination Sample',
theme: ThemeData(
primarySwatch: Colors.green,
),
home: Scaffold(body: CharacterListView(),),
);
}
class CharacterListView extends StatefulWidget {
@override
_CharacterListViewState createState() => _CharacterListViewState();
}
class _CharacterListViewState extends State<CharacterListView> {
static const _pageSize = 20;
final PagingController<int, dynamic> _pagingController = PagingController(firstPageKey: 0);
@override
void initState() {
_pagingController.addPageRequestListener((pageKey) {
_fetchPage(pageKey);
});
super.initState();
}
dynamic getDataFromApi(offset, limit) async {
var response = await http.get(
Uri.parse("https://dummyjson.com/products?limit=$limit&skip=$offset"),
);
if (response.statusCode == 200) {
var decodedData = jsonDecode(response.body);
return decodedData['products'];
} else {
return Future.error("Server Error !");
}
}
Future<void> _fetchPage(pageKey) async {
try {
final newItems = await getDataFromApi(pageKey, _pageSize);
final isLastPage = newItems.length < _pageSize;
if (isLastPage) {
_pagingController.appendLastPage(newItems);
} else {
final nextPageKey = pageKey + newItems.length;
_pagingController.appendPage(newItems, nextPageKey);
}
} catch (error) {
_pagingController.error = error;
}
}
@override
Widget build(BuildContext context) => RefreshIndicator(
onRefresh: () => Future.sync(
() => _pagingController.refresh(),
),
child: PagedListView<int, dynamic>.separated(
pagingController: _pagingController,
builderDelegate: PagedChildBuilderDelegate<dynamic>(
animateTransitions: true,
itemBuilder: (context, item, index) {
return ListTile(
leading: CircleAvatar(
radius: 20,
backgroundImage:
CachedNetworkImageProvider(item['thumbnail']),
),
title: Text(item['title']),
);
},
),
separatorBuilder: (context, index) => const Divider(),
),
);
@override
void dispose() {
_pagingController.dispose();
super.dispose();
}
}
pubspec.yaml의 dependencies에는 다음과 같이 설정했음.
dependencies:
flutter:
sdk: flutter
infinite_scroll_pagination: ^3.2.0
http: ^0.13.3
cached_network_image: ^3.2.3
dynamic 사용하지 않고 객체 사용하는 버전은 다음 파일에 같이 추가해 두었음.
'flutter > 기타' 카테고리의 다른 글
Getx - Reactive State manager 방식들 (0) | 2023.09.04 |
---|---|
Flutter를 Chrome에서 실행할 때 생기는 Cors문제 회피 (0) | 2023.08.13 |
Firebase로 회원 생성 / 로그인 (0) | 2022.05.19 |
RenderBox was not laid out: RenderRepaintBoundary 에러 (2) | 2022.05.19 |