You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter GetX底部导航返回触发空检查错误求助

GetX BottomNavigationBar 返回页面崩溃问题排查与解决

问题描述

使用GetX实现包含5个页面(优惠-分类-购物车-收藏-账户)的BottomNavigationBar时,从索引0切换到其他页面正常,但返回索引0时应用崩溃,抛出错误:

Null check operator used on a null value

项目已通过GetX Binding类按需初始化控制器,各页面有独立控制器,此前用相同逻辑结合TabBar未出现问题。

相关代码示例

HomePageController

class HomePageController extends GetxController {
  static HomePageController instance = HomePageController();

  late TextEditingController categoriesSearchController;

  @override
  void onInit() {
    super.onInit();
    categoriesSearchController = TextEditingController();
  }

  int bottomNavIndex = 0;

  changeBottomIndex(int index) {
    bottomNavIndex = index;
    update();
  }


  List<Widget> bottomScreens = const [
    Offers(),
    Categories(),
    Cart(),
    Favorite(),
    Account(),
  ];

  List<ItemModel> meatsList = [
    ItemModel(
      title: 'Thigh',
      image: 'assets/images/home_page/pin_thigh.png',
      description: '1 Kg',
      price: 1.72,
    ),
    ItemModel(
      title: 'Breast',
      image: 'assets/images/home_page/breasts2.jpg',
      description: '1 Kg',
      price: 1.65,
    ),
    ItemModel(
      title: 'lamb',
      image: 'assets/images/home_page/lamb.jpeg',
      description: '1 Kg',
      price: 6.55,
    ),
  ];
}

HomePage

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GetBuilder<HomePageController>(
      builder: (controller) => controller != null
          ? SafeArea(
              child: Scaffold(
                backgroundColor: AppColors.whiteColor,
                bottomNavigationBar: BottomNavigationBar(
                  items: controller.changingBottom(),
                  currentIndex: controller.bottomNavIndex,
                  type: BottomNavigationBarType.fixed,
                  selectedItemColor: AppColors.onBoardingButton,
                  onTap: (index) {
                    controller.changeBottomIndex(index);
                  },
                ),
                body: controller.bottomScreens[controller.bottomNavIndex],
              ),
            )
          : const Center(
              child: CircularProgressIndicator(),
            ),
    );
  }
}

Binding类

class Binding extends Bindings {
  @override
  void dependencies() {
    Get.put(() => DatabaseController());
    Get.lazyPut(() => AuthController());
    Get.lazyPut(() => HomePageController());
    Get.lazyPut(() => ProductsController());
    Get.lazyPut(() => CartController());
  }
}

解决方法

1. 消除控制器实例冲突

HomePageController中定义的static HomePageController instance = HomePageController();会手动创建实例,和GetX通过Get.lazyPut管理的实例不是同一个对象,导致GetBuilder绑定的控制器出现空指针。

修改:删除static instance定义,所有需要获取控制器的地方改用Get.find<HomePageController>()。

2. 移除页面列表的const修饰

bottomScreens用const修饰会缓存页面Widget,导致页面切换回来时,子页面的控制器无法正确初始化或已被回收,触发空指针。

修改:

// 去掉const关键字
List<Widget> bottomScreens = [
  Offers(),
  Categories(),
  Cart(),
  Favorite(),
  Account(),
];

3. 正确回收TextEditingController

控制器中的categoriesSearchController未在页面销毁时回收,可能导致内存泄漏或间接触发空指针,需添加回收逻辑:

@override
void onClose() {
  categoriesSearchController.dispose();
  super.onClose();
}

4. 简化GetBuilder判断

通过Binding初始化的控制器不会为null,可去掉controller != null的判断,简化代码:

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GetBuilder<HomePageController>(
      builder: (controller) => SafeArea(
        child: Scaffold(
          backgroundColor: AppColors.whiteColor,
          bottomNavigationBar: BottomNavigationBar(
            items: controller.changingBottom(),
            currentIndex: controller.bottomNavIndex,
            type: BottomNavigationBarType.fixed,
            selectedItemColor: AppColors.onBoardingButton,
            onTap: controller.changeBottomIndex,
          ),
          body: controller.bottomScreens[controller.bottomNavIndex],
        ),
      ),
    );
  }
}

5. 确认Binding注册时机

确保在App入口的GetMaterialApp中正确绑定初始化:

void main() {
  runApp(
    GetMaterialApp(
      initialBinding: Binding(),
      home: const HomePage(),
      // 其他配置项
    ),
  );
}

额外排查点

  • 检查子页面(如Offers)的控制器使用:确保所有子页面用Get.find()获取的控制器已在Binding中注册,且未被手动调用Get.delete()销毁。
  • 若子页面使用GetView,需确认泛型对应的控制器已正确初始化。

内容的提问来源于stack exchange,提问作者Muhammad Qazmouz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 13:45:24