CircularProgressIndicator
如果正在加载对另一部分广告的请求,我希望在列表末尾。我想它需要在onNotification
方法下完成,因为我在那里提出请求并且可能在此方法完成时禁用它?
代码类似于https://codinginfinite.com/flutter-future-builder-pagination/
你能告诉我我该怎么做吗?
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:..../ui/pages/home/page/AdvertisementCard.dart';
import 'package:.../ui/pages/home/page/model/AdvertisementList.dart';
import '../../SizedBox.dart';
import 'AdvertisementProdRepository.dart';
import 'BottomAppBar.dart';
import 'FAB.dart';
import 'model/AdvertisementList.dart';
class HomePage extends StatefulWidget {
final String jwt;
const HomePage(this.jwt);
@override
_HomePage createState() => _HomePage();
factory HomePage.fromBase64(String jwt) => HomePage(jwt);
}
class _HomePage extends State<HomePage> {
late final String jwt;
late Future<AdvertisementList> _listOfItems;
final searchTextController = TextEditingController();
@override
void initState() {
super.initState();
jwt = widget.jwt;
_listOfItems = AdvertisementProdRepository.fetchAdvertisements(1);
}
@override
Widget build(BuildContext context) => Scaffold(
body: Scaffold(
backgroundColor: const Color(0xFEF9F9FC),
floatingActionButtonLocation:
FloatingActionButtonLocation.centerDocked,
floatingActionButton: buildFAB(),
bottomNavigationBar: BuildBottomAppBar(),
body: Container(
padding: EdgeInsets.only(left: 25.0, right: 25, top: 25),
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Column(
children: [
TextFormField(
controller: searchTextController,
decoration: InputDecoration(
prefixIcon: Icon(Icons.search),
border: OutlineInputBorder(),
hintText: 'Szukaj',
fillColor: Color(0xffeeeeee),
filled: true),
),
buildSizedBox(20.0),
Padding(
padding: const EdgeInsets.only(left: 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
'Najnowsze ogłoszenia',
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.bold),
textAlign: TextAlign.left,
),
],
),
),
buildSizedBox(10.0),
FutureBuilder<AdvertisementList>(
future: _listOfItems,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(child: CircularProgressIndicator());
} else {
return Expanded(
child:
AdvertisementTile(advertisements: snapshot.data!),
);
}
},
),
],
),
),
),
);
}
class AdvertisementTile extends StatefulWidget {
final AdvertisementList advertisements;
AdvertisementTile({Key? key, required this.advertisements}) : super(key: key);
@override
State<StatefulWidget> createState() => AdvertisementTileState();
}
class AdvertisementTileState extends State<AdvertisementTile> {
AdvertisementLoadMoreStatus loadMoreStatus =
AdvertisementLoadMoreStatus.STABLE;
final ScrollController scrollController = new ScrollController();
late List<Advertisement> advertisements;
late int currentPageNumber;
bool _loading = false;
@override
void initState() {
advertisements = widget.advertisements.items;
currentPageNumber = widget.advertisements.pageNumber;
super.initState();
}
@override
void dispose() {
scrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return NotificationListener(
onNotification: onNotification,
child: Padding(
padding: const EdgeInsets.only(bottom: 28.0),
child: new ListView.separated(
padding: EdgeInsets.zero,
scrollDirection: Axis.vertical,
controller: scrollController,
itemCount: advertisements.length,
physics: const AlwaysScrollableScrollPhysics(),
itemBuilder: (_, index) {
return AdvertisementCard(data: advertisements[index]);
},
separatorBuilder: (BuildContext context, int index) {
return SizedBox(
height: 10,
);
},
),
),
);
}
bool onNotification(ScrollNotification notification) {
if (notification is ScrollUpdateNotification) {
if (scrollController.position.maxScrollExtent > scrollController.offset &&
scrollController.position.maxScrollExtent - scrollController.offset <=
50) {
if (loadMoreStatus == AdvertisementLoadMoreStatus.STABLE) {
loadMoreStatus = AdvertisementLoadMoreStatus.LOADING;
AdvertisementProdRepository.fetchAdvertisements(currentPageNumber + 1)
.then((advertisementObject) {
currentPageNumber = advertisementObject.pageNumber;
loadMoreStatus = AdvertisementLoadMoreStatus.STABLE;
setState(() => advertisements.addAll(advertisementObject.items));
});
}
}
}
return true;
}
}
enum AdvertisementLoadMoreStatus { LOADING, STABLE }