Flutter GetX底部导航返回触发空检查错误求助
问题描述
使用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
相关产品推荐
相关产品推荐

