Flutter地点搜索插件flutter_google_places的使用
Flutter地点搜索插件flutter_google_places的使用
简介
flutter_google_places
是一个用于Flutter应用的Google Places自动补全插件。它可以帮助用户在应用中快速查找和选择地点。以下是关于如何使用该插件的详细说明和完整示例代码。
快速开始
-
添加依赖 在
pubspec.yaml
文件中添加flutter_google_places
依赖,并确保使用最新版本:dependencies: flutter: sdk: flutter flutter_google_places: ^<last-version>
-
导入必要的包 在你的 Dart 文件中导入
flutter_google_places
和google_maps_webservice
包:import 'package:flutter/material.dart'; import 'package:flutter_google_places/flutter_google_places.dart'; import 'package:google_maps_webservice/places.dart'; import 'package:google_api_headers/google_api_headers.dart';
-
设置API密钥 你需要一个有效的 Google Places API 密钥。将其存储在一个常量中,例如:
const kGoogleApiKey = "YOUR_API_KEY";
-
创建主应用程序 下面是一个完整的示例代码,展示了如何使用
flutter_google_places
插件来实现地点搜索功能:
import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_google_places/flutter_google_places.dart';
import 'package:google_maps_webservice/places.dart';
import 'package:google_api_headers/google_api_headers.dart';
void main() {
runApp(RoutesWidget());
}
final customTheme = ThemeData(
primarySwatch: Colors.blue,
brightness: Brightness.dark,
accentColor: Colors.redAccent,
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4.00)),
),
contentPadding: EdgeInsets.symmetric(
vertical: 12.50,
horizontal: 10.00,
),
),
);
class RoutesWidget extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) => MaterialApp(
title: "My App",
theme: customTheme,
routes: {
"/": (_) => MyApp(),
"/search": (_) => CustomSearchScaffold(),
},
);
}
class MyApp extends StatefulWidget {
[@override](/user/override)
_MyAppState createState() => _MyAppState();
}
final homeScaffoldKey = GlobalKey<ScaffoldState>();
final searchScaffoldKey = GlobalKey<ScaffoldState>();
class _MyAppState extends State<MyApp> {
Mode _mode = Mode.overlay;
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
key: homeScaffoldKey,
appBar: AppBar(
title: Text("My App"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_buildDropdownMenu(),
ElevatedButton(
onPressed: _handlePressButton,
child: Text("搜索地点"),
),
ElevatedButton(
child: Text("自定义"),
onPressed: () {
Navigator.of(context).pushNamed("/search");
},
),
],
),
),
);
}
Widget _buildDropdownMenu() => DropdownButton(
value: _mode,
items: <DropdownMenuItem<Mode>>[
DropdownMenuItem<Mode>(
child: Text("Overlay"),
value: Mode.overlay,
),
DropdownMenuItem<Mode>(
child: Text("Fullscreen"),
value: Mode.fullscreen,
),
],
onChanged: (m) {
setState(() {
_mode = m;
});
},
);
void onError(PlacesAutocompleteResponse response) {
homeScaffoldKey.currentState.showSnackBar(
SnackBar(content: Text(response.errorMessage)),
);
}
Future<void> _handlePressButton() async {
// 显示输入自动补全并选择模式
// 然后获取选中的 Prediction
Prediction p = await PlacesAutocomplete.show(
context: context,
apiKey: kGoogleApiKey,
onError: onError,
mode: _mode,
language: "zh", // 设置为中文
decoration: InputDecoration(
hintText: '搜索',
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
borderSide: BorderSide(
color: Colors.white,
),
),
),
components: [Component(Component.country, "cn")], // 限制为中国
);
displayPrediction(p, homeScaffoldKey.currentState);
}
}
Future<Null> displayPrediction(Prediction p, ScaffoldState scaffold) async {
if (p != null) {
// 获取详细信息(经纬度)
GoogleMapsPlaces _places = GoogleMapsPlaces(
apiKey: kGoogleApiKey,
apiHeaders: await GoogleApiHeaders().getHeaders(),
);
PlacesDetailsResponse detail = await _places.getDetailsByPlaceId(p.placeId);
final lat = detail.result.geometry.location.lat;
final lng = detail.result.geometry.location.lng;
scaffold.showSnackBar(
SnackBar(content: Text("${p.description} - $lat/$lng")),
);
}
}
// 自定义搜索页面
// 你的小部件需要继承 [GooglePlacesAutocompleteWidget]
// 并且状态类需要继承 [GooglePlacesAutocompleteState]
class CustomSearchScaffold extends PlacesAutocompleteWidget {
CustomSearchScaffold()
: super(
apiKey: kGoogleApiKey,
sessionToken: Uuid().generateV4(),
language: "en",
components: [Component(Component.country, "uk")],
);
[@override](/user/override)
_CustomSearchScaffoldState createState() => _CustomSearchScaffoldState();
}
class _CustomSearchScaffoldState extends PlacesAutocompleteState {
[@override](/user/override)
Widget build(BuildContext context) {
final appBar = AppBar(title: AppBarPlacesAutoCompleteTextField());
final body = PlacesAutocompleteResult(
onTap: (p) {
displayPrediction(p, searchScaffoldKey.currentState);
},
logo: Row(
children: [FlutterLogo()],
mainAxisAlignment: MainAxisAlignment.center,
),
);
return Scaffold(key: searchScaffoldKey, appBar: appBar, body: body);
}
[@override](/user/override)
void onResponseError(PlacesAutocompleteResponse response) {
super.onResponseError(response);
searchScaffoldKey.currentState.showSnackBar(
SnackBar(content: Text(response.errorMessage)),
);
}
[@override](/user/override)
void onResponse(PlacesAutocompleteResponse response) {
super.onResponse(response);
if (response != null && response.predictions.isNotEmpty) {
searchScaffoldKey.currentState.showSnackBar(
SnackBar(content: Text("获取到结果")),
);
}
}
}
class Uuid {
final Random _random = Random();
String generateV4() {
// 生成 xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx / 8-4-4-4-12.
final int special = 8 + _random.nextInt(4);
return '${_bitsDigits(16, 4)}${_bitsDigits(16, 4)}-'
'${_bitsDigits(16, 4)}-'
'4${_bitsDigits(12, 3)}-'
'${_printDigits(special, 1)}${_bitsDigits(12, 3)}-'
'${_bitsDigits(16, 4)}${_bitsDigits(16, 4)}${_bitsDigits(16, 4)}';
}
String _bitsDigits(int bitCount, int digitCount) =>
_printDigits(_generateBits(bitCount), digitCount);
int _generateBits(int bitCount) => _random.nextInt(1 << bitCount);
String _printDigits(int value, int count) =>
value.toRadixString(16).padLeft(count, '0');
}
更多关于Flutter地点搜索插件flutter_google_places的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复