flutter/기타

infinite scroll 구현 - 패키지 예제 단순화 함

coens 2023. 8. 13. 11:44

플러터에서 무한스크롤을 구현하는 다음의 패키지가 있는데, 그 안의 예제가 좀 복잡해서 단순화 해 봄.

예제안의 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 사용하지 않고 객체 사용하는 버전은 다음 파일에 같이 추가해 두었음.

infinite_scroll_exam.zip
0.01MB