如何在Dart中存储photo_reference为字符串并获取Place API照片?
解决Dart中从Google Places API的photos数组提取photo_reference的问题
你遇到的核心问题是没处理好Google Places API返回的photos是数组类型,而非单个对象。你的代码里直接尝试对数组调用getString("photo_reference"),这肯定会报错——数组根本没有这个方法。咱们一步步来修正:
1. 修正Casino类的fromJson构造函数
先看返回的JSON结构:photos是包含多个photo对象的数组,每个photo对象里才存有photo_reference字段。你可以根据需求选两种处理方式:
方式一:只存第一个photo的reference(适合单图场景)
如果每个场所只需要展示一张图,直接取数组第一个元素的photo_reference即可:
import 'package:meta/meta.dart'; class Casino{ Casino({ @required this.name, @required this.id, @required this.photoReference, // 改为存储单个reference字符串 @required this.overview, this.favored, }); String name, id, overview, photoReference; bool favored; Casino.fromJson(Map json) : name = json["name"], // 先判断数组是否存在且非空,再提取第一个元素的photo_reference photoReference = (json["photos"] as List).isNotEmpty ? (json["photos"][0] as Map)["photo_reference"].toString() : null, id = json["place_id"].toString(), overview = json["overview"] ?? "", // 空值兜底,避免null异常 favored = false; }
方式二:存储所有photo的reference列表(适合多图场景)
如果需要展示该场所的所有图片,把存储字段改成列表类型:
import 'package:meta/meta.dart'; class Casino{ Casino({ @required this.name, @required this.id, @required this.photoReferences, // 改为列表类型 @required this.overview, this.favored, }); String name, id, overview; List<String> photoReferences; bool favored; Casino.fromJson(Map json) : name = json["name"], // 遍历photos数组,提取每个元素的photo_reference photoReferences = (json["photos"] as List) .map((photo) => (photo as Map)["photo_reference"].toString()) .toList(), id = json["place_id"].toString(), overview = json["overview"] ?? "", favored = false; }
2. 修正UI部分的代码
根据你选的方式,调整图片加载逻辑:
对应方式一(单个reference):
Widget build(BuildContext context){ return Card( child: Container( height:200.0, padding: EdgeInsets.all(10.0), child: Row( children: <Widget>[ casinoState.photoReference != null ? Hero( child: Image.network( "https://maps.googleapis.com/maps/api/place/photo?photoreference=${casinoState.photoReference}&sensor=false&maxheight=200&maxwidth=150&key=$key"), tag:casinoState.id, ) : Container(), // 其他UI元素... ], ), ), ); }
对应方式二(多个reference):
如果要显示第一张图,取列表第一个元素即可:
Widget build(BuildContext context){ return Card( child: Container( height:200.0, padding: EdgeInsets.all(10.0), child: Row( children: <Widget>[ casinoState.photoReferences != null && casinoState.photoReferences.isNotEmpty ? Hero( child: Image.network( "https://maps.googleapis.com/maps/api/place/photo?photoreference=${casinoState.photoReferences[0]}&sensor=false&maxheight=200&maxwidth=150&key=$key"), tag:casinoState.id, ) : Container(), // 其他UI元素... ], ), ), ); }
额外注意点
- 务必加空值判断,避免某些场所没有photos数组导致的空指针异常;
- 给
overview加?? ""兜底,防止字段为null时出现问题; - 确认你的Google Cloud Console已启用Places API,且API Key拥有对应权限,否则图片可能加载失败。
内容的提问来源于stack exchange,提问作者Moe
相关产品推荐
相关产品推荐

