Flutter: динамический начальный маршрут

Уважаемые,

Я использую пакет dart provider, который позволяет слушателям получать уведомления об изменениях в моделях как таковых.

Я могу обнаружить изменение в моем основном корневом дереве приложения, а также могу изменить строковое значение исходного маршрута, однако мой экран не обновляется. Пожалуйста, посмотрите ниже фрагмент кода и строки комментариев:

  void main() => runApp(_MyAppMain());

    class _MyAppMain extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MultiProvider(
          providers: [
            ChangeNotifierProvider<UserProvider>.value(
              value: UserProvider(),
            ),
            ChangeNotifierProvider<PhoneProvider>.value(
              value: PhoneProvider(),
            )
          ],
          child: Consumer<UserProvider>(
            builder: (BuildContext context, userProvider, _) {
              return FutureBuilder(
                future: userProvider.getUser(),
                builder: (BuildContext context, AsyncSnapshot<User> snapshot) {
                  if (!snapshot.hasData) {
                    return Center(
                      child: CircularProgressIndicator(),
                    );
                  }

                  final User user = snapshot.data;

                  String initialScreen = LoginScreen.path;

    // (1) I am able to get into the condition

                  if (user.hasActiveLogin()) {
                    initialScreen = HomeOneScreen.path;
                  }

                  return MaterialApp(
                    title: 'MyApp',
                    theme: ThemeData(
                      primarySwatch: Colors.green,
                      accentColor: Colors.blueGrey,
                    ),
                    initialRoute: initialScreen, 
 // (2) here the screen is not changing...?
                    routes: {
                      '/': (context) => null,
                      LoginScreen.path: (context) => LoginScreen(),
                      RegisterScreen.path: (context) => RegisterScreen(),
                      HomeOneScreen.path: (context) => HomeOneScreen(),
                      HomeTwoScreen.path: (context) => HomeTwoScreen(),
                      RegisterPhoneScreen.path: (context) => RegisterPhoneScreen(),
                      VerifyPhoneScreen.path: (context) => VerifyPhoneScreen(),
                    },
                  );
                },
              );
            },
          ),
        );
      }
    }

Пожалуйста, обратите внимание на следующее:

These are are paths static const strings
LoginScreen.path = "login"
RegisterScreen.path = "/register-screen"
HomeOneScreen.path = "home-one-screen"
HomeTwoScreen.path = "home-two-screen"
RegisterPhoneScreen.path = "/register-phone-screen"
VerifyPhoneScreen.path = "/verify-phone-screen"

Что мне не хватает для работы динамического initialRoute?

Огромное спасибо


person xiarnousx    schedule 28.07.2019    source источник


Ответы (1)


Согласно этой проблеме, описанной в проблемах с github, изменение первоначального маршрута недопустимо. По крайней мере, я так понял. Однако я заменил атрибут initialRoute на home attr. Таким образом, это изменение требует, чтобы initialScreen стал переменной виджета.

Изменения показаны ниже:

 void main() => runApp(_MyAppMain());

    class _MyAppMain extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MultiProvider(
          providers: [
            ChangeNotifierProvider<UserProvider>.value(
              value: UserProvider(),
            ),
            ChangeNotifierProvider<PhoneProvider>.value(
              value: PhoneProvider(),
            )
          ],
          child: Consumer<UserProvider>(
            builder: (BuildContext context, userProvider, _) {
              return FutureBuilder(
                future: userProvider.getUser(),
                builder: (BuildContext context, AsyncSnapshot<User> snapshot) {
                  if (!snapshot.hasData) {
                    return Center(
                      child: CircularProgressIndicator(),
                    );
                  }

                  final User user = snapshot.data;

// (1) This becomes a widget

                  Widget initialScreen = LoginScreen();



                  if (user.hasActiveLogin()) {
                    initialScreen = HomeOneScreen();
                  }

                  return MaterialApp(
                    title: 'MyApp',
                    theme: ThemeData(
                      primarySwatch: Colors.green,
                      accentColor: Colors.blueGrey,
                    ),
                    home: initialScreen, 
 // (2) here the initial route becomes home attr.
                    routes: {
                      '/': (context) => null,
                      LoginScreen.path: (context) => LoginScreen(),
                      RegisterScreen.path: (context) => RegisterScreen(),
                      HomeOneScreen.path: (context) => HomeOneScreen(),
                      HomeTwoScreen.path: (context) => HomeTwoScreen(),
                      RegisterPhoneScreen.path: (context) => RegisterPhoneScreen(),
                      VerifyPhoneScreen.path: (context) => VerifyPhoneScreen(),
                    },
                  );
                },
              );
            },
          ),
        );
      }
    }

Также обратите внимание на мой RegistrationScreen при успешном ответе api, который я сделал Navigator.of(context).pop()

Спасибо

person xiarnousx    schedule 28.07.2019