Flutter项目中humanReadableAddress填充TextField报错问题
问题分析
你遇到的红黄色错误界面是空指针异常导致的:在SearchDestinationPage的build方法中,你使用!强制解包pickUpLocation,但当页面加载时,pickUpLocation可能还未被初始化(比如地理编码请求尚未完成、页面跳转时数据未同步),此时强制解包会触发崩溃。
虽然日志中humanReadableAddress输出正常,但这只代表地理编码请求完成时的值,不代表页面加载时pickUpLocation已经被赋值。
解决方案
方案1:使用Consumer监听状态变化(推荐)
通过Consumer监听AppInfo的变化,仅当pickUpLocation更新时才设置文本框内容,同时避免强制解包:
修改SearchDestinationPage的build方法:
@override Widget build(BuildContext context) { return Scaffold( body: SingleChildScrollView( child: Consumer<AppInfo>( builder: (context, appInfo, child) { // 安全获取地址,空值时用空字符串兜底 String userAddress = appInfo.pickUpLocation?.humanReadableAddress ?? ""; pickUpTextEditingController.text = userAddress; return Column( children: [ // 保留原有的Card、文本框等组件代码 Card( elevation: 10, child: Container( // ... 原代码不变 ), ), // ... 原代码不变 ], ); }, ), ), ); }
方案2:在initState中初始化并监听状态
如果不想使用Consumer,可以在页面初始化时获取一次地址,并监听AppInfo的更新:
@override void initState() { super.initState(); final appInfo = Provider.of<AppInfo>(context, listen: false); // 初始化时获取地址 String initialAddress = appInfo.pickUpLocation?.humanReadableAddress ?? ""; pickUpTextEditingController.text = initialAddress; // 监听AppInfo变化,实时更新地址 appInfo.addListener(() { String updatedAddress = appInfo.pickUpLocation?.humanReadableAddress ?? ""; if (pickUpTextEditingController.text != updatedAddress) { pickUpTextEditingController.text = updatedAddress; } }); } @override Widget build(BuildContext context) { // 移除原build方法中设置控制器的代码,其余代码保留 return Scaffold( body: SingleChildScrollView( child: Column( // ... 原代码不变 ), ), ); }
额外优化:确保pickUpLocation始终被初始化
修改common_methods.dart中的地理编码方法,即使API请求失败,也初始化pickUpLocation,避免空值:
static Future<String> convertGeoGraphicCoOrdinatesIntoHumanReadableAddress( Position position, BuildContext context) async { String humanReadableAddress = ""; String apiGeoCodingUrl = "https://maps.googleapis.com/maps/api/geocode/json?latlng=${position.latitude},${position.longitude}&key=$googleMapKey"; var responseFromAPI = await sendRequestToAPI(apiGeoCodingUrl); if (responseFromAPI != "error") { humanReadableAddress = responseFromAPI["results"][0]["formatted_address"]; print("humanReadableAddress = " + humanReadableAddress); } else { // API请求失败时设置提示文本 humanReadableAddress = "无法获取当前地址"; } AddressModel model = AddressModel(); model.humanReadableAddress = humanReadableAddress; model.longitudePosition = position.longitude; model.latitudePosition = position.latitude; Provider.of<AppInfo>(context, listen: false).updatePickUpLocation(model); return humanReadableAddress; }
内容的提问来源于stack exchange,提问作者Abhijit Malakar
相关产品推荐
相关产品推荐

