我正在嘗試將地址轉換為坐標,我使用 Google Place API 獲取地址,我得到的是這樣的 json 物件:
"predictions" : [
{
"description" : "Nueva Galicia 342, Urdi?ola, Saltillo, Coah., México",
"matched_substrings" : [
{
"length" : 13,
"offset" : 0
},
{
"length" : 3,
"offset" : 14
}
],
我的代碼是:
import 'dart:convert';
import 'package:http/http.dart';
class Suggestion {
final String placeId;
final String description;
Suggestion(this.placeId, this.description);
@override
String toString() {
return 'Suggestion(description: $description, placeId: $placeId)';
}
}
class PlaceApiProvider {
final client = Client();
PlaceApiProvider(this.sessionToken);
final sessionToken;
final apiKey = 'API KEY';
Future<List<Suggestion>> fetchSuggestions(
String input,
) async {
final request =
'https://maps.googleapis.com/maps/api/place/autocomplete/json?input=$input&types=address&language=es-Es&components=country:mx&key=$apiKey&sessiontoken=$sessionToken';
final response = await client.get(Uri.parse(request));
final requestCoordinates =
'https://maps.googleapis.com/maps/api/geocode/json?address=$address&key=$apiKey';
final responseCoordinates = await client.get(Uri.parse(requestCoordinates));
print(response.body);
print(responseCoordinates.body);
if (response.statusCode == 200) {
final result = json.decode(response.body);
if (result['status'] == 'OK') {
return result['predictions']
.map<Suggestion>((p) => Suggestion(p['place_id'], p['description']))
.toList();
}
if (result['status'] == 'ZERO_RESULTS') {
return [];
}
throw Exception(result['error_message']);
} else {
throw Exception('Failed to fetch suggestion');
}
}
}
我知道我需要從回應中獲取描述,然后在 requestCoordinates 的 $address 中使用它,但我不知道該怎么做,有人可以幫忙嗎?
uj5u.com熱心網友回復:
你可以使用flutter社區提供的flutter_google_places包。它給你谷歌地方自動完成小部件。如果您需要代碼和解釋,請告訴我
uj5u.com熱心網友回復:
我實作了 flutter_google_place 包,但在我使用的 Flutter 版本(2.10.1)中,空安全版本給我帶來了一些問題。代碼是這樣的:
class SearchButton extends StatefulWidget {
const SearchButton({Key? key}) : super(key: key);
@override
State<SearchButton> createState() => _SearchButtonState();
}
class _SearchButtonState extends State<SearchButton> {
final _destinationController = TextEditingController();
final ApiKey = "AIzaSyDUJ9IM2aSBxfQBozwn4aFt70FDaEGtfu0";
@override
void dispose() {
_destinationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final newLocation = Provider.of<ClientRequest>(context);
final sessionToken = const Uuid().v4();
Mode _mode = Mode.overlay;
void one rror(PlacesAutocompleteResponse response) {
SnackBar(
content: Text(response.errorMessage),
);
}
Future<void> displayPrediction(Prediction p) async {
if (p != null) {
GoogleMapsPlaces _places = GoogleMapsPlaces(
apiKey: ApiKey,
apiHeaders: await const GoogleApiHeaders().getHeaders(),
);
PlacesDetailsResponse detail =
await _places.getDetailsByPlaceId(p.placeId);
final lat = detail.result.geometry?.location.lat;
final lng = detail.result.geometry?.location.lng;
SnackBar(
content: Text("${p.description} - $lat/$lng"),
);
print(detail);
}
}
Future<void> _handlePressButton() async {
Prediction p = await PlacesAutocomplete.show(
context: context,
apiKey: ApiKey,
one rror: one rror,
mode: _mode,
language: "fr",
decoration: InputDecoration(
hintText: 'Search',
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
borderSide: const BorderSide(
color: Colors.white,
),
),
),
components: [Component(Component.country, "mx")],
);
displayPrediction(p);
}
return MaterialButton(
onPressed: _handlePressButton,
child: Container(
padding: const EdgeInsets.only(left: 3, right: 3),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
boxShadow: const [
BoxShadow(
color: Colors.grey,
spreadRadius: 1,
blurRadius: 3,
offset: Offset(0, 3),
),
]),
child: TextField(
controller: _destinationController,
decoration: InputDecoration(
enabled: false,
prefixIcon: const Icon(Icons.search),
filled: true,
fillColor: const Color(0xffEDEDED),
hintText: 'Ingresa una nueva dirección',
contentPadding:
const EdgeInsets.only(left: 14.0, bottom: 8.0, top: 8.0),
disabledBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.white),
borderRadius: BorderRadius.circular(20),
),
border: const OutlineInputBorder(),
),
),
),
),
);
}
}
錯誤在:response.errorMessage -> 引數型別“字串?” 不能分配給引數型別'String' p.placeId -> 引數型別'String?' 不能分配給引數型別“字串”。等待 PlacesAutocomplete.show -> 型別為“預測?”的值 不能分配給“預測”型別的變數。嘗試更改變數的型別,或將右手型別轉換為“預測”。
任何線索如何解決這個問題?
uj5u.com熱心網友回復:
更新您的代碼
Future<void> _handlePressButton() async {
//make prediction nullable
Prediction? p = await PlacesAutocomplete.show(
context: context,
radius: 10000000,
types: [],
logo:Text(''),
strictbounds: false,
mode: Mode.overlay,
language: "fr",
components: [
Component(Component.country, "fr"),
Component(Component.country, "in"),
Component(Component.country, "UK")
],
apiKey: kGoogleApiKey);
displayPrediction(p!);
}
Future<void> displayPrediction(Prediction p) async {
if (p != null) {
PlacesDetailsResponse detail =
await _places.getDetailsByPlaceId(p.placeId!);
String? placeId = p.placeId;
double lat = detail.result.geometry!.location.lat;
double lng = detail.result.geometry!.location.lng;
print(p.description);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/427060.html
