I'm creating an app with a Scaffold that contains:
- A
FutureBuilderin the body that creates aPageViewas its child when data is loaded. - A
BottomNavigationBarthat syncs with thePageViewfor a more intuitive navigation.
Functionality-wise, everything works fine. I can swipe left and right between pages and the currentIndex gets updated correctly in the BottomNavigationBar, and if I tap on the BottomNavigationBar elements the PageView will animate to the correct page as expected.
However... performance is really bad when switching between pages, even in Profile mode.
After a lot of investigation, I've confirmed that lag is only present if I update the currentIndex of the BottomNavigationBar.
If I don't update the BottomNavigationBar, animations remain very smooth when switching between pages, both when swiping on the PageView and when tapping on the BottomNavigationBar elements themselves.
I can also confirm that this happens exactly the same when using setState and when using Provider. I was really hoping that it was just the setState method being inefficient... but no luck :(
For the setState impementation, this is what I'm doing:
On the PageView:
onPageChanged: (page) {
setState(() {
_selectedIndex = page;
});
}
On the BottomBarNavigation:
onTap: _onTappedBar,
currentIndex: _selectedIndex
and below:
void _onTappedBar(int value) {
_pageController.animateToPage(value, duration: Duration(milliseconds: 500), curve: Curves.ease);
setState(() {
_selectedIndex = value;
});
}
If I comment out both setState methods, the app becomes buttery smooth again and I can use the BottomNavigationBar correctly as well - it just doesn't update the selected item.
Interestingly enough, if I ONLY comment out the line inside both setState methods (_selectedIndex = page; and _selectedIndex = value;) but leave the methods there, the app still lags all the same even though the setState methods are completely empty and aren't updating anything...??
And this is the Provider version:
On the PageView:
onPageChanged: (page) {
Provider.of<BottomNavigationBarProvider>(context, listen: false).currentIndex = page;
}
On the BottomBarNavigation:
onTap: _onTappedBar,
currentIndex: Provider.of<BottomNavigationBarProvider>(context).currentIndex,
and below:
void _onTappedBar(int value) {
Provider.of<BottomNavigationBarProvider>(context, listen: false).currentIndex = value;
pageController.animateToPage(value, duration: Duration(milliseconds: 500), curve: Curves.ease);
}
As said, just as laggy as the setState version :(
Any idea of what's causing this lag and how to fix this? I really don't know what else to try.