Consider the following StatelessWidget
:
class SwitchScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final testService = Provider.of<TestService>(context); // Line 1
Future( () {
Navigator.of(context).push( // Segment 2
MaterialPageRoute(builder: (context) => TestScreen()) // Segment 2
); // Segment 2
});
return Scaffold(body: Center( child: Text("lol") ) );
}
}
The widget is directly below the root in the widget tree and wrapped by a ChangeNotifierProvider
:
void main() => runApp(new Main());
class Main extends StatefulWidget {
_MainState createState() => _MainState();
}
class _MainState extends State<Main> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'SampleProgram',
home: ChangeNotifierProvider<TestService>(
builder: (_) { return TestService(); } ,
child: SwitchScreen(),
),
);
}
}
The service associated with the provider, TestService
, is currently empty. TestScreen
is simply another StatelessWidget
which includes AppBar
wrapped inside a Scaffold
.
I would expect the program to finish rendering the SwitchScreen
, navigate to TestScreen
to fulfill the future, and finally render the AppBar
inside TestScreen
. However, every time it enters the TestScreen
view, something appears to trigger a rebuild of SwitchScreen
. The app then bounces back to SwitchScreen
, moves to TestScreen
to fulfill the future, and repeats this process. By using debug Print statements I'm sure that the build
method of SwitchScreen
is called immediately after TestScreen
finishes rendering.
The interesting thing is that if I comment out Line 1, the build
method won't be re-triggered. Similarly if I replace the entirety of Segment 2 with anything else, say a print statement, the build
method won't keep firing either. I suspected that Navigator
is resulting in some value change in TestService
, forcing SwitchScreen
to rebuild, so I overrode the notifyListeners
method in TestService
since this method is the only way SwitchScreen
can be affected by TestService
.
class TestService with ChangeNotifier {
@override
void notifyListeners() {
print("Triggering SwitchScreen's build method");
}
}
But no string is printed out. Right now I'm very curious about what's causing the rebuilding and what roles do the Provider and the Navigator play in this. Any help would be really appreciated.