Closed DZESU closed 3 years ago
Hi @DZESU ,
If you call retryLastFailedRequest
when in an error state, it should request the last page again to the listener.
If this is not happening, I'll need you to reproduce the issue in a minimal toy project so that I can help you.
I'm closing the issue for now, but feel free to continue the discussion.
Thank you
Hi @EdsonBueno
Here I able to reproduce a small sample code that causes this bug. What is found is changing childAspectRatio to bigger than 1, the retryLastFailedRequest
function will work. But the childAspectRatio is kind of not consistent with my production project. Hope this helps you fix the bug. Any questions about the sample code please let me know.
import 'package:flutter/material.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final PagingController<int, String> pagingController =
PagingController(firstPageKey: 0, invisibleItemsThreshold: 10);
int page = 0;
@override
void initState() {
super.initState();
pagingController.addPageRequestListener((pageKey) {
page = pageKey;
_appendList();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Test List"),
),
body: Container(
child: RefreshIndicator(
onRefresh: () async {
pagingController.refresh();
},
child: CustomScrollView(
slivers: [
SliverPadding(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
sliver: _itemListSection(context),
),
],
),
),
),
);
}
_loading(){
return Center(child: CircularProgressIndicator());
}
_Item(BuildContext context, String item) {
return Container(
padding: EdgeInsets.all(10),
child: Text("item $item"),
);
}
void _appendList() {
List<String> items = List.generate(10, (index) => "${(pagingController?.itemList?.length??0) + index}");
if((pagingController?.itemList?.length??0) < 60) {
pagingController.appendPage(items, page + 1);
}else{
pagingController.error = Exception("Error Test");
}
}
_errorItem() {
return Container(
color: Colors.green,
child: TextButton(onPressed: (){
pagingController.retryLastFailedRequest();
}, child: Text("Retry",style: TextStyle(color: Colors.white),)),
);
}
Widget _itemListSection(BuildContext context) {
return PagedSliverGrid<int, String>(
pagingController: pagingController,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 3/4,
),
builderDelegate: PagedChildBuilderDelegate<String>(
itemBuilder: (context, item, index) => _Item(context, item),
firstPageProgressIndicatorBuilder: (context) => _loading(),
newPageProgressIndicatorBuilder: (context) => _loading(),
noItemsFoundIndicatorBuilder: (context) => _errorItem(),
newPageErrorIndicatorBuilder: (context) => _errorItem(),
firstPageErrorIndicatorBuilder: (context) {
return _errorItem();
}),
);
}
}
Thanks @DZESU . I'll take a look.
@EdsonBueno I don't know if you will continue the development. But, I think this issue should be reopened so that it can receive some attention.
I have, also, stumbled on this issue. And, I think page_layout_builder.dart
is the main decision maker in this case.
Here's the _buildListItemWidget()
function from page_layout_builder.dart
.
/// Connects the [_pagingController] with the [_builderDelegate] in order to
/// create a list item widget and request more items if needed.
Widget _buildListItemWidget(
BuildContext context,
int index,
List<ItemType> itemList,
) {
if (!_hasRequestedNextPage) {
final newPageRequestTriggerIndex =
max(0, _itemCount - _invisibleItemsThreshold);
final isBuildingTriggerIndexItem = index == newPageRequestTriggerIndex;
if (_hasNextPage && isBuildingTriggerIndexItem) {
// Schedules the request for the end of this frame.
WidgetsBinding.instance?.addPostFrameCallback((_) {
_pagingController.notifyPageRequestListeners(_nextKey!);
});
_hasRequestedNextPage = true;
}
}
Suppose, I have loaded some pages of total 33 items. After scrolling down in one fling, when I tried to load next page, there is an error. Following is the log just before the error:
[log] _buildListItemWidget: _hasNextPage: true, _itemCount: 36, index: 33, newPageRequestTriggerIndex: 33, _invisibleItemsThreshold: 3
Now, newPageErrorIndicator
is visible. If I call retryLastFailedRequest()
function, _buildListItemWidget()
is called two times. Following is the log just after I called retryLastFailedRequest()
function:
[log] _buildListItemWidget: _hasNextPage: true, _itemCount: 36, index: 34, newPageRequestTriggerIndex: 33, _invisibleItemsThreshold: 3 [log] _buildListItemWidget: _hasNextPage: true, _itemCount: 36, index: 35, newPageRequestTriggerIndex: 33, _invisibleItemsThreshold: 3
If I scroll a bit to top direction, I see following log:
[log] _buildListItemWidget: _hasNextPage: true, _itemCount: 36, index: 33, newPageRequestTriggerIndex: 33, _invisibleItemsThreshold: 3
This log triggers the next-page request because _invisibleItemsThreshold
of 3 has been met (36 minus 33). When I called the retryLastFailedRequest()
function, _buildListItemWidget()
receives an index of 34 & 35, which skips the next-page request.
I do not know if you can help me, but I want to request you that if you see a possible solution, please let me know. At the end, if you do not, all I can try is to call following myself:
// Schedules the request for the end of this frame.
WidgetsBinding.instance?.addPostFrameCallback((_) {
_pagingController.notifyPageRequestListeners(_nextKey!);
});
_hasRequestedNextPage = true;
Hi @EdsonBueno this seems to be still an issue
Hello there, I kinda wonder if this is the expected behavior or it's a bug, when I call
retryLastFailedRequest
method it doesn't do anything. And upon looking at the code all it does it to seterror = null
. Is this when you intent it to be? How do I use this method?