skip to Main Content

I am making a flutter app where i am handling routing and navigation using the onGenerateRoute in main app where I am passing the following :

  static Route<dynamic> generateRoute(RouteSettings settings) {
    debugPrint('ROUTING TO ${settings.name}');    
    switch (settings.name) {
      case HomeScreen.id:
        return MaterialPageRoute(builder: (_) => const HomeScreen());
      case EditProfileScreen.id:
        return MaterialPageRoute(
            builder: (_) =>
                EditProfileScreen(user: settings.arguments as User));
      case FollowerFollowingScreen.id:
        return MaterialPageRoute(
            builder: (_) =>
                FollowerFollowingScreen(userId: settings.arguments as String));
      case ThreadScreen.id:
        return MaterialPageRoute(
            builder: (_) => ThreadScreen(
                  post:
                      (settings.arguments as ThreadNavigationArguments).parent,
                  isParentAComment:
                      (settings.arguments as ThreadNavigationArguments)
                          .isParentAComment,
                  postId:
                      (settings.arguments as ThreadNavigationArguments).postId,
                ));
      case ProfileScreen.id:
        return MaterialPageRoute(
          builder: (_) => ProfileScreen(user: settings.arguments as User),
        );

      case LoginScreen.id:
        return MaterialPageRoute(builder: (_) => const LoginScreen());
      case SettingsScreen.id:
        return MaterialPageRoute(builder: (_) => const SettingsScreen());
      case ChooseTopicScreen.id:
        return MaterialPageRoute(builder: (_) => const ChooseTopicScreen());
      case AddPostBody.id:
        return MaterialPageRoute(
            builder: (_) => AddPostBody(user: settings.arguments as User));

      default:
        return MaterialPageRoute(
            builder: (_) => Scaffold(
                  body: Center(
                    child: Text('No route for ${settings.name}'),
                  ),
                ));
    }
  }

Also in iniTialRoute I have passed jwtToken != null && jwtToken!.isNotEmpty ? HomeScreen.id : LoginScreen.id . HomeScreen.id is '/' while LoginScreen.id is /login . However whenever app is restarting (without loggin in) or when app starts for the first time, it is first routing to / and then to /login as evident from the statement which i printed in the console

enter image description here

So the problem happening is the on hitting back on login screen I am going to home screen as / is below /login in the stack. And on app restart it is always first routing to / (and not necessarily HomeScreen.id which is also /, as I checked by setting it to /home) and then going to /login. why is this occurring even though I have set initialRoute appropriately? Any fixes?

2

Answers


  1. I had the same issue in my application, as i came to know MaterialApp do add the / in the stack initially after your defined screen added to the stack. and if you press back button it pops you added screen and as the / is still in the stack it will be showed.

    Simplest fix is to make new screen for ‘/’ with any name like InitScreen and use Navigator.pushNamedAndRemoveUntil() from there.

    You can do your ternary operation for next screen there jwtToken != null && jwtToken!.isNotEmpty ? HomeScreen.id : LoginScreen.id

    Login or Signup to reply.
  2. the problem is that your route name is treated as a deep link if it starts with a slash and therefor all previous routes are also pushed as well.

    You could change your route names so that they dont start with a slash, or override onGenerateRoute of the MaterialApp to return your first route inside of a List of Routes instead.

    This is a small example that shows both ways (you can use either one):

    void main() => runApp(_build());
    
    Widget _page(String txt, String navigateTo) {
      return Builder(builder: (BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
          body: ElevatedButton(
            onPressed: () => Navigator.of(context).pushNamed(navigateTo),
            child: Text("this is $txt and goes to $navigateTo"),
          ),
        );
      });
    }
    
    Widget _build() {
      return MaterialApp(
        initialRoute: "a/login",
        onGenerateInitialRoutes: (String initialRoute) => <Route<dynamic>>[
          MaterialPageRoute<Widget>(builder: (BuildContext context) {
            return _page("/initial", "a/login");
          }),
        ],
        onGenerateRoute: (RouteSettings settings) {
          print("ROUTING TO ${settings.name}");
          if (settings.name == "a/") {
            return MaterialPageRoute<Widget>(builder: (BuildContext context) {
              return _page("a/", "a/login");
            });
          } else if (settings.name == "a/login") {
            return MaterialPageRoute<Widget>(builder: (BuildContext context) {
              return _page("a/login", "a/");
            });
          } else {
            return MaterialPageRoute<Widget>(builder: (BuildContext context) {
              return Scaffold(
                appBar: AppBar(),
                body: const Text("no page"),
              );
            });
          }
        },
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search