Skip to content

Instantly share code, notes, and snippets.

@ykrods
Last active March 21, 2023 03:15
Show Gist options
  • Save ykrods/3abbe700ba93e42d84d83409faf624c1 to your computer and use it in GitHub Desktop.
Save ykrods/3abbe700ba93e42d84d83409faf624c1 to your computer and use it in GitHub Desktop.
/**
* Flutter で PullToRefresh + InfiniteScroll 実装例
*
* # ポイント
* - Mixin で InfinateScroll の実装を分割している
*
* # 課題
* - ListView に対して ScrollController が一つしか指定できないので他にスクロール関連でやりたいことがある場合は
* このままの形では使えない
*/
import 'dart:async';
import 'package:flutter/material.dart';
abstract class LoadMoreInterface {
Future<void> loadMore();
}
mixin LoadMoreMixin<T extends StatefulWidget> on State<T> implements LoadMoreInterface {
Future<void>? loading;
late ScrollController _scrollController;
void initState() {
super.initState();
_scrollController = ScrollController()..addListener(_scrollListener);
}
void dispose() {
super.dispose();
_scrollController.removeListener(_scrollListener);
}
void _scrollListener() {
if (loading == null && _scrollController.position.extentAfter < 100) {
loading = loadMore().then((_) {
loading = null;
}).catchError((e) {
loading = null;
});
}
}
}
class ListPage extends StatefulWidget {
const ListPage({ super.key });
@override
State<ListPage> createState() => _ListPageState();
}
class _ListPageState extends State<ListPage> with LoadMoreMixin {
int itemCount = 20;
loadMore() async {
print("load start");
await Future.delayed(Duration(seconds: 1));
setState(() {
itemCount += 20;
print("itemCount: ${itemCount}");
});
}
@override
void initState() {
super.initState();
_refresh();
}
void _refresh() {
print("refresh");
itemCount = 20;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: RefreshIndicator(
color: Colors.white,
backgroundColor: Colors.blue,
onRefresh: () async => setState(_refresh),
child: ListView.builder(
// これを忘れると動かないので注意
controller: _scrollController,
itemCount: itemCount,
itemBuilder: (context, index) => ListTile(title: Text(index.toString()))
)
)
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment