RouteAware didPushNext не вызывается при нажатии двух маршрутов одновременно - PullRequest
2 голосов
/ 24 апреля 2020

При одновременной передаче двух маршрутов в Navigator и использовании RouteAware для получения обновленной информации о текущем состоянии, didPopNext () первого маршрута не вызывается.

Похоже, что RouteObserver.didPu sh () (который будет вызывать didPushNext) вызывается для обоих маршрутов перед вызовом didChangeDependencies () FirstWiget, где я подписываюсь на routeObserver.

Это то, что я ожидаю и что я получаю при нажатии кнопки маршрутизирует один за другим и ожидает появления виджета:

I/flutter (30927): Navigator.push(FirstWidget)
I/flutter (30927): didChangeDependencies FirstWidget
I/flutter (30927): didPush FirstWidget
I/flutter (30927): build FirstWidget
I/flutter (30927): Navigator.push(SecondWidget)
I/flutter (30927): didPushNext FirstWidget
I/flutter (30927): didChangeDependencies SecondWidget
I/flutter (30927): didPush SecondWidget
I/flutter (30927): build SecondWidget
I/flutter (30927): didChangeDependencies FirstWidget
I/flutter (30927): didChangeDependencies FirstWidget
I/flutter (30927): build FirstWidget

При одновременном нажатии обоих:

I/flutter (30927): Navigator.push(FirstWidget)
I/flutter (30927): Navigator.push(SecondWidget)
I/flutter (30927): didChangeDependencies FirstWidget
I/flutter (30927): didPush FirstWidget
I/flutter (30927): build FirstWidget
I/flutter (30927): didChangeDependencies SecondWidget
I/flutter (30927): didPush SecondWidget
I/flutter (30927): build SecondWidget
I/flutter (30927): didChangeDependencies FirstWidget
I/flutter (30927): build FirstWidget

Это пример выполнения:

import 'package:flutter/material.dart';

RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();

void main() {
  runApp(MaterialApp(
    title: 'Navigation Test',
    home: StartWidget(),
    navigatorObservers: <NavigatorObserver>[routeObserver],
  ));
}

class StartWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Start'),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            RaisedButton(
              child: Text('Open both routes'),
              onPressed: () {
                print("Navigator.push(FirstWidget)");
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => FirstWidget()),
                );
                print("Navigator.push(SecondWidget)");
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => SecondWidget()),
                );
              },
            ),
            RaisedButton(
              child: Text('Open FirstWidget'),
              onPressed: () {
                print("Navigator.push(FirstWidget)");
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => FirstWidget()),
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}

class FirstWidget extends StatefulWidget {
  @override
  _FirstWidgetState createState() => _FirstWidgetState();
}

class _FirstWidgetState extends RouteAwareState<FirstWidget> {
  Widget build(BuildContext context) {
    print("build $widget");
    return Scaffold(
      appBar: AppBar(
        title: Text('FirstWidget'),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            RaisedButton(
              child: Text('Open SecondWidget'),
              onPressed: () {
                print("Navigator.push(SecondWidget)");
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => SecondWidget()),
                );
              },
            ),
            RaisedButton(
              child: Text('back'),
              onPressed: () {
                Navigator.pop(context);
              },
            ),
          ],
        ),
      ),
    );
  }
}

class SecondWidget extends StatefulWidget {
  @override
  _SecondWidgetState createState() => _SecondWidgetState();
}

class _SecondWidgetState extends RouteAwareState<SecondWidget> {
  @override
  Widget build(BuildContext context) {
    print("build $widget");
    return Scaffold(
      appBar: AppBar(
        title: Text('SecondWidget'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('back'),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
      ),
    );
  }
}

abstract class RouteAwareState<T extends StatefulWidget> extends State<T>
    with RouteAware {
  @override
  void didChangeDependencies() {
    print("didChangeDependencies $widget");
    routeObserver.subscribe(this, ModalRoute.of(context)); //Subscribe it here
    super.didChangeDependencies();
  }

  @override
  void didPush() {
    print('didPush $widget');
  }

  @override
  void didPopNext() {
    print('didPopNext $widget');
  }

  @override
  void didPop() {
    print('didPop $widget');
  }

  @override
  void didPushNext() {
    print('didPushNext $widget');
  }

  @override
  void dispose() {
    print("dispose $widget");
    routeObserver.unsubscribe(this);
    super.dispose();
  }
}

Примечание: отредактировано для непосредственного включения кода.

1 Ответ

0 голосов
/ 06 мая 2020

При размещении

WidgetsBinding.instance.addPostFrameCallback()

между двумя вызовами Navigator.push() FirstWidget регистрируется правильно, и вызывается обратный вызов didPushNext FirstWidget.

См. проблема флаттера # 55949 для более подробной информации.

...