getx icon indicating copy to clipboard operation
getx copied to clipboard

Nested Route Rebuild Issue

Open Minessential opened this issue 10 months ago • 3 comments

Hello everyone, I found a bug when using nested routes.
Specifically, my page nesting structure is as follows:

  static final routes = [
    GetPage(
      participatesInRootNavigator: true,
      name: _Paths.HOME,
      page: () => const HomeView(),
      binding: HomeBinding(),
      children: [
        GetPage(name: _Paths.NEWS, page: () => const NewsView(), binding: NewsBinding()),
        GetPage(name: _Paths.LOGIN, page: () => const LoginView(), binding: LoginBinding()),
      ],
    ),
    GetPage(name: _Paths.SETTING, page: () => const SettingView(), binding: SettingBinding()),
  ];

News Page

On the login page, there is a button to open the settings page.

Login Page
However, when I click the button, the news page is rebuilt before navigating to the settings page.

Animation During Navigation

Settings Page

Below is the key code of the project:

file: lib/app/routes/app_routes.dart

part of 'app_pages.dart';
// DO NOT EDIT. This is code generated via package:get_cli/get_cli.dart

abstract class Routes {
  Routes._();
  static const HOME = _Paths.HOME;
  static const LOGIN = _Paths.HOME + _Paths.LOGIN;
  static const NEWS = _Paths.HOME + _Paths.NEWS;
  static const SETTING = _Paths.SETTING;
}

abstract class _Paths {
  _Paths._();
  static const HOME = '/home';
  static const LOGIN = '/login';
  static const NEWS = '/news';
  static const SETTING = '/setting';
}

file: lib/app/routes/app_pages.dart

import 'package:get/get.dart';

import '../modules/home/bindings/home_binding.dart';
import '../modules/home/login/bindings/login_binding.dart';
import '../modules/home/login/views/login_view.dart';
import '../modules/home/news/bindings/news_binding.dart';
import '../modules/home/news/views/news_view.dart';
import '../modules/home/views/home_view.dart';
import '../modules/setting/bindings/setting_binding.dart';
import '../modules/setting/views/setting_view.dart';

part 'app_routes.dart';

class AppPages {
  AppPages._();

  static const INITIAL = Routes.HOME;

  static final routes = [
    GetPage(
      participatesInRootNavigator: true,
      name: _Paths.HOME,
      page: () => const HomeView(),
      binding: HomeBinding(),
      children: [
        GetPage(name: _Paths.LOGIN, page: () => const LoginView(), binding: LoginBinding()),
        GetPage(name: _Paths.NEWS, page: () => const NewsView(), binding: NewsBinding()),
      ],
    ),
    GetPage(name: _Paths.SETTING, page: () => const SettingView(), binding: SettingBinding()),
  ];
}

file: lib/app/modules/home/views/home_view.dart

import 'package:fluent_get_test/app/routes/app_pages.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../controllers/home_controller.dart';

class HomeView extends GetView<HomeController> {
  const HomeView({super.key});

  @override
  Widget build(BuildContext context) {
    return GetRouterOutlet.builder(
      route: Routes.HOME,
      builder: (context) {
        return Scaffold(
          appBar: AppBar(title: const Text('HomeView'), centerTitle: true),
          body: GetRouterOutlet(initialRoute: Routes.NEWS, anchorRoute: Routes.HOME),
          bottomNavigationBar: IndexedRouteBuilder(
            routes: const [Routes.NEWS, Routes.LOGIN],
            builder: (context, routes, index) {
              final delegate = context.delegate;
              return BottomNavigationBar(
                currentIndex: index,
                items: const [
                  BottomNavigationBarItem(icon: Icon(Icons.article), label: 'News'),
                  BottomNavigationBarItem(icon: Icon(Icons.login), label: 'Login'),
                ],
                onTap: (index) => delegate.toNamed(routes[index]),
              );
            },
          ),
        );
      },
    );
  }
}

file: lib/main.dart

import 'package:flutter/material.dart';

import 'package:get/get.dart';

import 'app/routes/app_pages.dart';

void main() {
  runApp(
    GetMaterialApp.router(
      title: "Application",
      defaultTransition: Transition.fade,
      transitionDuration: Duration(seconds: 1),
      getPages: AppPages.routes,
    ),
  );
}

file: lib/app/modules/home/login/views/login_view.dart

import 'package:fluent_get_test/app/routes/app_pages.dart';
import 'package:flutter/material.dart';

import 'package:get/get.dart';

import '../controllers/login_controller.dart';

class LoginView extends GetView<LoginController> {
  const LoginView({super.key});
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('LoginView'), centerTitle: true),
      body: Center(
        child: Column(
          children: [
            const Text('LoginView is working', style: TextStyle(fontSize: 20)),
            FilledButton(
              child: const Text('Setting'),
              onPressed: () {
                Get.toNamed(Routes.SETTING);
              },
            ),
          ],
        ),
      ),
    );
  }
}

file: lib/app/modules/home/news/views/news_view.dart

import 'package:flutter/material.dart';

import 'package:get/get.dart';

import '../controllers/news_controller.dart';

class NewsView extends GetView<NewsController> {
  const NewsView({super.key});
  @override
  Widget build(BuildContext context) {
    print('NewsView build!');
    return Scaffold(
      appBar: AppBar(title: const Text('NewsView'), centerTitle: true),
      backgroundColor: Colors.green,
      body: const Center(child: Text('NewsView is working', style: TextStyle(fontSize: 20))),
    );
  }
}

##more info flutter : Channel main, 3.31.0-1.0.pre.405, on Microsoft Windows [Version 10.0.27808.1000] get: 5.0.0-release-candidate-9.3.2 get cli: 1.9.1

Minessential avatar Apr 04 '25 13:04 Minessential

Hello, can you provide a github repository for replicating bugs

summer-boythink avatar Apr 06 '25 06:04 summer-boythink

Hello, can you provide a github repository for replicating bugs

yes, the repository is here Minessential/flutter_get_test

Minessential avatar Apr 07 '25 06:04 Minessential

I confirm the same problem occurs to me. Glad to help any way I can :)

LuisGMM avatar Apr 27 '25 10:04 LuisGMM