I'm working with FutureBuilder and I initialize _future in InitState
as mentioned here.
Despite this, FutureBuilder
re-build itself every time I switch page with the BottomNavigationBar
.
Code Sample:
class _HomeViewState extends State<HomeView> {
late final Future<List<DocumentSnapshot<Object?>>> _futureSerieA;
@override
void initState() {
super.initState();
_futureSerieA = getScheduled("Serie A");
}
@override
Widget build(BuildContext context) {
return SizedBox.expand(
child: SingleChildScrollView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(0,0,0,0),
child: Container(
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.transparent)
)
),
child: Theme(
data: Theme.of(context).copyWith(dividerColor: Colors.transparent),
child: FutureBuilder(
future: _futureSerieA,
builder: (context, AsyncSnapshot<List<DocumentSnapshot>> snapshot) {
if (snapshot.hasData) {
List<String> scheduled = [];
for (var DOC in snapshot.data!) {
scheduled.add(DOC.id);
}
return ...
How could I disable FutureBuilder re-build when browsing between pages of BottomNavigationBar?
BottomNavBar:
class _LoggedHandleState extends State<LoggedHandle> {
);
double height = AppBar().preferredSize.height;
int _selectedPage = 1;
final _pageOptions = [
const BetView(),
const HomeView(),
const UserView()
];
@override
Widget build(BuildContext context) {
return Scaffold(
...
),
bottomNavigationBar: BottomNavigationBar(
unselectedItemColor: Colors.white60,
backgroundColor: Colors.red,
selectedItemColor: Colors.white,
currentIndex: _selectedPage,
onTap: (int index) {
setState(() {
_selectedPage = index;
});
},
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.receipt),
label: 'Schedina',
),
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle),
label: 'Account',
),
]),
body: _pageOptions[_selectedPage],
);
}
}
CodePudding user response:
When browsing between pages of bottom navigation bar, your state is not maintained. This behaviour causes the widget to rebuild every time.
You can use Indexed Stack https://api.flutter.dev/flutter/widgets/IndexedStack-class.html
@override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: BottomNavigationBar(
onTap: (index) {
setState(() {
current_tab = index;
});
},
currentIndex: current_tab,
items: [
BottomNavigationBarItem(
...
),
BottomNavigationBarItem(
...
),
],
),
body: IndexedStack(
children: <Widget>[
PageOne(),
PageTwo(),
],
index: current_tab,
),
);
}
Although this is the best solution, it will load all your widgets once the IndexedStack is loaded. I found a Lazy Loading Indexed Stack util to load your widgets when and only the first time they are created https://github.com/okaryo/lazy_load_indexed_stack