Flutter地理位置服务插件places_service的使用

发布于 1周前 作者 yibo5220 来自 Flutter

Flutter地理位置服务插件places_service的使用

简介

places_service 是一个封装了 Google Places API 的 Flutter 插件,通过 google_maps_webservice 包提供了一个易于使用的接口,方便你在代码中处理和调用 Google Places API。

使用方法

1. 初始化

首先,你需要初始化 places_service 并传入你的 Google API Key。这一步通常在应用启动时完成,如果你使用的是 FilledStacks 推荐的架构,可以在 StartUpViewModel 中进行初始化。

// 初始化 places_service
_placesService.initialize(
  apiKey: 'PUT_YOUR_KEY_HERE', // 替换为你的 Google API Key
);
2. 获取自动补全建议

初始化完成后,你可以使用 getAutoComplete 函数来获取地址的自动补全建议。这个函数会返回一个包含多个建议的列表。

// 获取自动补全建议
final autoCompleteSuggestions = await _placesService.getAutoComplete('cape town');

autoCompleteSuggestions 将包含一系列与输入地址相关的建议,例如:

  • Cape Town, Western Cape, South Africa
  • Cape Town International Airport, Cape Town, South Africa
  • Cape Town Stadium, Cape Town, South Africa
3. 获取地点详情

当你从自动补全建议中选择了某个地点后,你可以通过 getPlaceDetails 函数获取该地点的详细信息。你需要传递一个地点 ID(通常是自动补全建议中的 place_id)。

// 获取地点详情
final placeDetails = await _placesService.getPlaceDetails('ID_FROM_AUTO_COMPLETE');

placeDetails 将包含该地点的所有可用信息,例如名称、地址、经纬度、电话号码等。

完整示例 Demo

以下是一个完整的示例项目,展示了如何在 Flutter 应用中使用 places_service 插件。

import 'package:flutter/material.dart';
import 'package:places_service/places_service.dart'; // 引入 places_service 包
import 'package:stacked/stacked.dart'; // 如果你使用的是 Stacked 架构

void main() async {
  // 初始化依赖注入
  await setupLocator();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomeView(),
    );
  }
}

class HomeView extends StatefulWidget {
  [@override](/user/override)
  _HomeViewState createState() => _HomeViewState();
}

class _HomeViewState extends State<HomeView> {
  final _placesService = locator<PlacesService>(); // 获取 places_service 实例
  String _searchText = '';
  List<AutoCompletePrediction> _suggestions = [];
  PlaceDetails? _selectedPlace;

  [@override](/user/override)
  void initState() {
    super.initState();
    // 初始化 places_service
    _placesService.initialize(apiKey: 'YOUR_API_KEY'); // 替换为你的 Google API Key
  }

  Future<void> _getAutoCompleteSuggestions() async {
    if (_searchText.isNotEmpty) {
      try {
        // 获取自动补全建议
        final suggestions = await _placesService.getAutoComplete(_searchText);
        setState(() {
          _suggestions = suggestions;
        });
      } catch (e) {
        print('Error fetching suggestions: $e');
      }
    }
  }

  Future<void> _getPlaceDetails(String placeId) async {
    try {
      // 获取地点详情
      final placeDetails = await _placesService.getPlaceDetails(placeId);
      setState(() {
        _selectedPlace = placeDetails;
      });
    } catch (e) {
      print('Error fetching place details: $e');
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Google Places Service Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            TextField(
              onChanged: (value) {
                setState(() {
                  _searchText = value;
                });
                _getAutoCompleteSuggestions();
              },
              decoration: InputDecoration(
                labelText: 'Search for a place',
                border: OutlineInputBorder(),
              ),
            ),
            SizedBox(height: 20),
            Expanded(
              child: ListView.builder(
                itemCount: _suggestions.length,
                itemBuilder: (context, index) {
                  final suggestion = _suggestions[index];
                  return ListTile(
                    title: Text(suggestion.description ?? ''),
                    onTap: () {
                      _getPlaceDetails(suggestion.placeId!);
                    },
                  );
                },
              ),
            ),
            if (_selectedPlace != null)
              Padding(
                padding: const EdgeInsets.only(top: 20),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text('Selected Place: ${_selectedPlace!.name}'),
                    Text('Address: ${_selectedPlace!.formattedAddress}'),
                    Text('Latitude: ${_selectedPlace!.geometry?.location.lat}'),
                    Text('Longitude: ${_selectedPlace!.geometry?.location.lng}'),
                  ],
                ),
              ),
          ],
        ),
      ),
    );
  }
}

更多关于Flutter地理位置服务插件places_service的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter地理位置服务插件places_service的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter应用中使用places_service插件来获取地理位置服务的代码示例。这个插件允许你搜索地点、获取当前位置附近的地点等。

首先,你需要在pubspec.yaml文件中添加places_service依赖:

dependencies:
  flutter:
    sdk: flutter
  places_service: ^0.x.x  # 请替换为最新版本号

然后,运行flutter pub get来安装依赖。

接下来,是一个简单的示例代码,展示如何使用places_service插件来搜索地点和获取当前位置附近的地点。

import 'package:flutter/material.dart';
import 'package:places_service/places_service.dart';
import 'package:geolocator/geolocator.dart';
import 'package:geocoding/geocoding.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Places Service Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final PlacesService _placesService = PlacesService();
  List<Prediction> _suggestions = [];
  List<Place> _nearbyPlaces = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Places Service Demo'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          children: [
            TextField(
              decoration: InputDecoration(
                labelText: 'Search Place',
                suffixIcon: IconButton(
                  icon: Icon(Icons.search),
                  onPressed: _searchPlace,
                ),
              ),
              onChanged: (value) async {
                setState(() {
                  _suggestions = await _placesService.getAutocompletePredictions(value);
                });
              },
            ),
            SizedBox(height: 16),
            Expanded(
              child: _suggestions.isEmpty
                  ? Center(child: Text('No suggestions'))
                  : ListView.builder(
                      itemCount: _suggestions.length,
                      itemBuilder: (context, index) => ListTile(
                        title: Text(_suggestions[index].description),
                        onTap: () async {
                          final PlaceDetails placeDetails =
                              await _placesService.getDetailsByPlaceId(_suggestions[index].placeId);
                          // 这里你可以处理获取到的placeDetails,比如显示详情
                          print(placeDetails.toJson());
                        },
                      ),
                    ),
            ),
            SizedBox(height: 16),
            ElevatedButton(
              onPressed: _getNearbyPlaces,
              child: Text('Get Nearby Places'),
            ),
            SizedBox(height: 16),
            Expanded(
              child: _nearbyPlaces.isEmpty
                  ? Center(child: Text('No nearby places'))
                  : ListView.builder(
                      itemCount: _nearbyPlaces.length,
                      itemBuilder: (context, index) => ListTile(
                        title: Text(_nearbyPlaces[index].name),
                        subtitle: Text(_nearbyPlaces[index].vicinity),
                      ),
                    ),
            ),
          ],
        ),
      ),
    );
  }

  Future<void> _searchPlace() async {} // 这个方法为空,因为搜索逻辑已经在TextField的onChanged中处理

  Future<void> _getNearbyPlaces() async {
    bool serviceEnabled;
    LocationPermission permission;

    // Test if location services are enabled.
    serviceEnabled = await Geolocator.isLocationServiceEnabled();
    if (!serviceEnabled) {
      return Future.error('Location services are disabled.');
    }

    permission = await Geolocator.checkPermission();
    if (permission == LocationPermission.denied) {
      permission = await Geolocator.requestPermission();
      if (permission == LocationPermission.denied) {
        return Future.error('Location permissions are denied');
      }
    }
    if (permission == LocationPermission.deniedForever) {
      return Future.error(
          'Location permissions are permanently denied, we cannot request permissions.');
    }

    Position position = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.high);
    List<Placemark> placemarks =
        await placemarkFromCoordinates(position.latitude, position.longitude);

    PlaceSearchRequest request = PlaceSearchRequest(
      location: LatLng(position.latitude, position.longitude),
      radius: 1500,
      type: ['restaurant'],
    );

    _nearbyPlaces = await _placesService.searchNearby(request);
    setState(() {});
  }
}

在这个示例中:

  1. 搜索地点:在TextField中输入地点名称,会触发自动完成建议的获取。
  2. 获取附近地点:点击“Get Nearby Places”按钮,应用会请求当前位置,并搜索附近的餐厅(你可以根据需要修改搜索类型)。

请注意,这个示例假设你已经处理好了必要的权限请求(如位置权限)。此外,places_servicegeolocator插件可能需要你添加额外的配置到AndroidManifest.xmlInfo.plist文件中,以便正确请求权限和访问位置服务。

确保你阅读并遵循这些插件的官方文档中的配置步骤,以确保一切正常工作。

回到顶部