Reputation: 327
In a State class, despite not calling setState() call, it is rebuilt with new items when the widget is returned from Navigator.pop(). How could this happen?
On my simplified code below, the ListView
is rebuilt whenever I clicked a button and pop the pushed widget.
Is it because Navigator.push()
disposes a current widget and the widget is re-rendered after Navigator.pop()
?
class _TestState extends State<Test> {
List<int> initialList = [];
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FlatButton(
onPressed: () async {
var nothing = await Navigator.of(context).push(
MaterialPageRoute(builder: (_context) => PushedWidget()),
);
// the State is rebuilt without calling setState()
initialList.add(1);
},
child: Text('test'),
),
body: Container(
child: ListView.builder(
itemCount: initialList.length,
itemBuilder: (context, idx) {
return Text('${initialList[idx]}');
},
),
),
);
}
}
class PushedWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(leading: IconButton(onPressed: () => _pop(context), icon: Icon(Icons.close))),
);
}
void _pop(BuildContext context) {
Navigator.of(context).pop('popped');
}
}
I've read docs and codes of implementation. But I couldn't find the answer to this question.
Upvotes: 0
Views: 153
Reputation: 1706
Navigator maintains a stack-based history of child widgets. I am considering that you already know about the data structure Stack. Navigator.push
and Navigator.push
works same like Stack. When we navigate to another screen, we use the push methods and Navigator widget adds the new screen onto the top of the stack. Whereas, the pop methods would remove that screen from the stack.
Upvotes: 1