Каковы внутренние реализации Navigator.push () и Navigator.pop ()?

В классе State, несмотря на то, что не вызывается вызов setState (), он перестраивается с новыми элементами, когда виджет возвращается из Navigator.pop (). Как такое могло произойти?

В моем упрощенном коде ниже ListView перестраивается всякий раз, когда я нажимаю кнопку и открываю нажатый виджет.

Это потому, что Navigator.push() удаляет текущий виджет, а виджет повторно отрисовывается после 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');
  }
}

Я читал документы и коды реализации. Но я не нашел ответа на этот вопрос.


person wurikiji    schedule 23.01.2019    source источник


Ответы (1)


Navigator поддерживает историю дочерних виджетов на основе стека. Я считаю, что вы уже знаете о структуре данных Stack. Navigator.push и Navigator.push работают так же, как Stack. Когда мы переходим на другой экран, мы используем методы push, а виджет Navigator добавляет новый экран в верхнюю часть стека. В то время как методы pop удаляют этот экран из стека.

person Ali Hussam    schedule 23.01.2019
comment
Спасибо за Ваш ответ. Интересно, будет ли push стек кешированный (уже визуализированный) виджет или просто виджет типа, поэтому повторно отрендерите его. - person wurikiji; 23.01.2019
comment
keepState управляет сохранением виджетов маршрута и объектов рендеринга. Если вы установите для него значение false, тогда, когда другой маршрут помещается поверх, все поддерево отбрасывается до тех пор, пока этот маршрут не появится. - person Ali Hussam; 23.01.2019
comment
Я очень ценю это! Спасибо большое! - person wurikiji; 23.01.2019