is there any option to keep one controller for two widgets? I have 3 buttons to change view, two of them use the same paging controller, everything works fine until it switches to the third view. Then, after back to the first or second view, the controller stop working.
class ViewsScreen extends StatefulWidget {
const ViewsScreen({Key? key}) : super(key: key);
@override
State<ViewsScreen> createState() => _ViewsScreenState();
}
class _ViewsScreenState extends State<ViewsScreen> {
int _view = 1;
final _pagingController = PagingController<int, Item>(
firstPageKey: 1,
);
@override
void dispose() {
_pagingController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Container(
width: double.infinity,
height: 40,
child: Row(
children: [
_pageButton(Icons.one_k, 'view1', 1),
_pageButton(Icons.two_k, 'view2', 2),
_pageButton(Icons.three_k, 'view3', 3),
],
),
),
Expanded(
child: _view == 1
? View12(
view: 1,
controller: _pagingController,
)
: _view == 2
? View12(
view: 2,
controller: _pagingController,
)
: View3()),
],
),
);
}
Widget _pageButton(IconData icon, String name, int view) {
return Expanded(
child: InkWell(
onTap: () {
setState(() {
_view = view;
});
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(icon),
Text(name),
],
),
),
);
}
}
View12 only changes the display of the list depending on the view parameter, but uses the same controller.
class View12 extends StatefulWidget {
final int view;
final PagingController<int, Item> controller;
const View12(
{Key? key, required this.view, required this.controller})
: super(key: key);
@override
_View12ViewState createState() => _View12ViewState();
}
class _View12ViewState extends State<View12> {
@override
void initState() {
widget.controller.addPageRequestListener((pageKey) {
//fetching data from service
context.read<ViewModel>().fetchPage(pageKey, widget.controller);
});
super.initState();
}
@override
Widget build(BuildContext context) {
return RefreshIndicator(
onRefresh: () => Future.sync(
() => widget.controller.refresh(),
),
child: PagedListView.separated(
pagingController: widget.controller,
separatorBuilder: (context, index) =>
Container(height: 1, color: Colors.black),
builderDelegate: PagedChildBuilderDelegate<Item>(
itemBuilder: (context, item, index) {
if (widget.view == 1)
return ItemGallery(
item: item,
);
if (widget.view == 2)
return ItemList(
item: item,
);
return Container();
},
),
),
);
}
}
Fetching method
Future<void> fetchPage(
int pageKey, PagingController<int, Offer> controller) async {
try {
final newItems = await loadData(pageKey);
if (isLastPage) {
controller.appendLastPage(newItems);
} else {
final nextPageKey = pageKey 1;
controller.appendPage(newItems, nextPageKey);
}
} catch (error) {
controller.error = error;
}
}
Error description after returning from view3 to view12:
CodePudding user response:
Use it like this,
final PagingController<int, Item> _pagingController =
PagingController(firstPageKey: 1);
CodePudding user response:
Future<void> _fetchPage(int pageKey) async {
try {
const _pageSize = 3;
final newItems = await loadData(pageKey);
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;
}
} }
change your fetching method like this