Flutter点击InkWell的onTap时出现Unexpected null value错误求助
Flutter InkWell点击触发Unexpected null value空值错误
点击编辑图标(InkWell组件)触发imagePickerOption函数时,抛出Unexpected null value空值错误,错误栈信息如下:
======== Exception caught by gesture =============================================================== The following TypeErrorImpl was thrown while handling a gesture: Unexpected null value. When the exception was thrown, this was the stack: dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 294:49 throw_ dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 855:63 nullCheck packages/get/get_navigation/src/extension_navigation.dart 36:39 ExtensionBottomSheet.bottomSheet packages/agriplus/Registration%20Screens/Signup%2520Screens/signup_screen_5.dart 48:9 imagePickerOption packages/flutter/src/material/ink_well.dart 1154:21 handleTap packages/flutter/src/gestures/recognizer.dart 275:24 invokeCallback packages/flutter/src/gestures/tap.dart 654:11 handleTapUp packages/flutter/src/gestures/tap.dart 311:5 [_checkUp] packages/flutter/src/gestures/tap.dart 244:7 handlePrimaryPointer packages/flutter/src/gestures/recognizer.dart 630:9 handleEvent packages/flutter/src/gestures/pointer_router.dart 98:12 [_dispatch] packages/flutter/src/gestures/pointer_router.dart 143:9 <fn> dart-sdk/lib/_internal/js_dev_runtime/private/linked_hash_map.dart 21:13 forEach packages/flutter/src/gestures/pointer_router.dart 141:17 [_dispatchEventToRoutes] packages/flutter/src/gestures/pointer_router.dart 127:7 route packages/flutter/src/gestures/binding.dart 488:19 handleEvent packages/flutter/src/gestures/binding.dart 468:14 dispatchEvent packages/flutter/src/rendering/binding.dart 333:11 dispatchEvent packages/flutter/src/gestures/binding.dart 413:7 [_handlePointerEventImmediately] packages/flutter/src/gestures/binding.dart 376:5 handlePointerEvent packages/flutter/src/gestures/binding.dart 323:7 [_flushPointerEventQueue] packages/flutter/src/gestures/binding.dart 292:9 [_handlePointerDataPacket] lib/_engine/engine/platform_dispatcher.dart 1319:13 invoke1 lib/_engine/engine/platform_dispatcher.dart 303:5 invokeOnPointerDataPacket lib/_engine/engine/pointer_binding.dart 168:39 [_onPointerData] lib/_engine/engine/pointer_binding.dart 791:20 <fn> lib/_engine/engine/pointer_binding.dart 720:14 <fn> lib/_engine/engine/pointer_binding.dart 317:16 loggedHandler dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 574:37 _checkAndCall dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 579:39 dcall Handler: "onTap" Recognizer: TapGestureRecognizer#c150a debugOwner: GestureDetector state: possible won arena finalPosition: Offset(320.8, 411.0) finalLocalPosition: Offset(20.8, 15.1) button: 1 sent tap down ====================================================================================================
相关代码
图片选择弹窗函数
File? pickedImage; void imagePickerOption() { Get.bottomSheet( SingleChildScrollView( child: ClipRRect( borderRadius: const BorderRadius.only( topLeft: Radius.circular(10.0), topRight: Radius.circular(10.0), ), child: Container( color: Colors.white, height: 250, child: Padding( padding: const EdgeInsets.all(8.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const Text( "Select Image From", style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), textAlign: TextAlign.center, ), const SizedBox( height: 10, ), ElevatedButton.icon( onPressed: () async { pickImage( ImageSource.camera, ); }, icon: const Icon( Icons.camera, color: Colors.white, ), label: const Text( "CAMERA", style: TextStyle( color: Colors.white, ), ), ), const SizedBox( height: 10, ), ElevatedButton.icon( onPressed: () async { pickImage( ImageSource.gallery, ); }, icon: const Icon( Icons.image, color: Colors.white, ), label: const Text( "GALLERY", style: TextStyle( color: Colors.white, ), ), ), const SizedBox( height: 10, ), ElevatedButton.icon( onPressed: () { Get.back(); }, icon: const Icon( Icons.close, color: Colors.white, ), label: const Text( "CANCEL", style: TextStyle( color: Colors.white, ), ), ), ], ), ), ), ), ), ); }
图片选择函数
void pickImage(ImageSource imageType) async { try { final photo = await ImagePicker().pickImage(source: imageType); if (photo == null) return; final tempImage = File(photo.path); setState(() { pickedImage = tempImage; }); Get.back(); } catch (error) { debugPrint(error.toString()); } }
InkWell所在布局代码
Stack( children: [ Container( width: 120, height: 120, decoration: BoxDecoration( border: Border.all( width: 4, color: Theme.of(context).scaffoldBackgroundColor, ), boxShadow: [ BoxShadow( spreadRadius: 2, blurRadius: 10, color: Colors.black.withOpacity(0.1), offset: const Offset(0, 10), ) ], shape: BoxShape.circle, ), child: ClipOval( child: Image.network( profilePicture, width: 120, height: 120, fit: BoxFit.cover, ), ), ), Positioned( bottom: 0, right: 0, child: InkWell( onTap: imagePickerOption, child: Container( height: 40, width: 40, decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( width: 4, color: Theme.of(context).scaffoldBackgroundColor, ), color: const Color(0XFF00B251), ), child: const Icon( Icons.edit_outlined, color: Colors.white, ), ), ), ), ], ),
错误原因分析
从错误栈可定位,空值错误发生在GetX的ExtensionBottomSheet.bottomSheet方法内部的空值检查,核心原因是GetX无法获取有效导航上下文:
- 项目根组件使用普通
MaterialApp而非GetX要求的GetMaterialApp,导致GetX无法初始化导航上下文。 - 调用
Get.bottomSheet时未传入有效context参数。
修复方案
方案1:替换根组件为GetMaterialApp
将项目入口的MaterialApp替换为GetMaterialApp,确保GetX能正确管理全局导航上下文:
void main() { runApp(const GetMaterialApp( home: YourHomePage(), )); }
方案2:手动传入context调用Get.bottomSheet
若无法替换根组件,调用Get.bottomSheet时手动传入当前页面的context:
void imagePickerOption(BuildContext context) { Get.bottomSheet( // 原有弹窗内容 context: context, ); } // 修改InkWell的onTap: InkWell( onTap: () => imagePickerOption(context), // 其他代码 )
额外检查
确认profilePicture变量不为空字符串,避免Image.network加载空URL引发潜在错误。
内容的提问来源于stack exchange,提问作者Mr Fin
相关产品推荐
相关产品推荐

