Flutter地点自动完成搜索插件google_places_autocomplete_flutter的使用

Flutter地点自动完成搜索插件google_places_autocomplete_flutter的使用

google_places_autocomplete_flutter 是一个基于 google_places_flutter 的插件,用于在 Flutter 应用中实现地点自动完成功能。通过该插件,用户可以方便地输入地址,并获得相关的建议。

添加依赖到 pubspec.yaml

首先,在项目的 pubspec.yaml 文件中添加 google_places_autocomplete_flutter 依赖:

dependencies:
  flutter:
    sdk: flutter
  google_places_autocomplete_flutter: ^1.0.6

然后运行 flutter pub get 命令以获取该依赖包。

Google AutoComplete TextField Widget 代码

以下是一个完整的示例代码,展示了如何在 Flutter 应用中使用 google_places_autocomplete_flutter 插件:

import 'package:flutter/material.dart';
import 'package:google_places_autocomplete_flutter/google_places_autocomplete_flutter.dart';
import 'package:google_places_autocomplete_flutter/model/prediction.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: '地点自动完成搜索示例'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, this.title = ''}) : super(key: key);

  final String title;

  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  TextEditingController controller = TextEditingController();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            SizedBox(height: 20),
            placesAutoCompleteTextField(),
          ],
        ),
      ),
    );
  }

  placesAutoCompleteTextField() {
    return Container(
      padding: EdgeInsets.symmetric(horizontal: 20),
      child: GooglePlaceAutoCompleteFlutterTextField(
          textEditingController: controller,
          googleAPIKey: "YOUR_GOOGLE_API_KEY",
          inputDecoration: InputDecoration(hintText: "搜索您的位置"),
          debounceTime: 800,
          countries: ["in", "fr"],
          types: ['country'],
          language: 'en',
          isLatLngRequired: true,
          getPlaceDetailWithLatLng: (Prediction prediction) {
            print("placeDetails" + prediction.lng.toString());
          },
          itmClick: (Prediction prediction) {
            controller.text = prediction.description!;
            controller.selection = TextSelection.fromPosition(
                TextPosition(offset: prediction.description!.length));
          }
      ),
    );
  }
}

更多关于Flutter地点自动完成搜索插件google_places_autocomplete_flutter的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter地点自动完成搜索插件google_places_autocomplete_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter应用中使用google_places_autocomplete_flutter插件来实现地点自动完成搜索功能的示例代码。这个插件可以帮助你集成Google Places API,从而提供地点搜索的自动完成功能。

首先,确保你已经在pubspec.yaml文件中添加了google_places_autocomplete_flutter依赖:

dependencies:
  flutter:
    sdk: flutter
  google_places_autocomplete_flutter: ^2.0.0 # 请检查最新版本号

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

接下来,你需要在你的Flutter应用中配置API密钥。请确保你已经从Google Cloud Platform获取了Places API的API密钥,并遵循Google的指南来启用Places API。

下面是一个简单的示例,展示如何使用google_places_autocomplete_flutter

import 'package:flutter/material.dart';
import 'package:google_places_autocomplete_flutter/google_places_autocomplete_flutter.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Google Places Autocomplete Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Google Places Autocomplete Demo'),
        ),
        body: PlacesAutocompleteDemo(),
      ),
    );
  }
}

class PlacesAutocompleteDemo extends StatefulWidget {
  @override
  _PlacesAutocompleteDemoState createState() => _PlacesAutocompleteDemoState();
}

class _PlacesAutocompleteDemoState extends State<PlacesAutocompleteDemo> {
  final _apiKey = 'YOUR_GOOGLE_PLACES_API_KEY'; // 请替换为你的API密钥
  PlaceResult? _selectedPlace;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          TextField(
            decoration: InputDecoration(
              labelText: 'Search for a place',
              suffixIcon: IconButton(
                icon: Icon(Icons.search),
                onPressed: _presentSearchDialog,
              ),
            ),
            onChanged: (value) {
              // Do something with the search input
            },
          ),
          SizedBox(height: 20),
          if (_selectedPlace != null)
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Text('Selected Place:', style: TextStyle(fontWeight: FontWeight.bold)),
                Text(_selectedPlace!.description ?? ''),
                Text('Place ID: ${_selectedPlace!.placeId ?? ''}'),
              ],
            ),
        ],
      ),
    );
  }

  Future<void> _presentSearchDialog() async {
    final result = await showSearch(
      context: context,
      delegate: PlacesSearchDelegate(
        apiKey: _apiKey,
        mode: Mode.fullscreen, // 或者使用 Mode.overlay
      ),
    );

    if (result != null) {
      setState(() {
        _selectedPlace = result;
      });
    }
  }
}

class PlacesSearchDelegate extends SearchDelegate<PlaceResult?> {
  final String apiKey;
  final Mode mode;

  PlacesSearchDelegate({required this.apiKey, required this.mode});

  @override
  List<Widget> buildActions(BuildContext context) {
    return [
      IconButton(
        icon: Icon(Icons.clear),
        onPressed: () {
          query = '';
          showSuggestions(context);
        },
      ),
    ];
  }

  @override
  Widget buildLeading(BuildContext context) {
    return IconButton(
      icon: AnimatedIcon(
        icon: AnimatedIcons.menu_arrow,
        progress: transitionAnimation!,
      ),
      onPressed: () {
        close(context, null);
      },
    );
  }

  @override
  Widget buildResults(BuildContext context) {
    if (query.isEmpty) {
      return Center(child: Text('Please enter a search term.'));
    }

    // 在这里你可以处理搜索结果的显示,但本示例中假设我们已经选择了结果
    return Container(); // 实际上,结果应该在选择后通过回调处理
  }

  @override
  Widget buildSuggestions(BuildContext context) {
    final suggestions = query.isEmpty
        ? []
        : _fetchSuggestions(query);

    return PlacesAutocompleteWidget(
      apiKey: apiKey,
      onPlaceSelected: (PlaceResult place) {
        close(context, place);
      },
      mode: mode,
      bias: query, // 可选的,用于指导搜索结果的地理位置偏好
    );
  }

  Future<List<Prediction>> _fetchSuggestions(String query) async {
    final response = await http.get(Uri.parse(
      'https://maps.googleapis.com/maps/api/place/autocomplete/json',
    ), headers: <String, String>{
      'Content-Type': 'application/json; charset=UTF-8',
      'Access-Control-Allow-Origin': '*',
    }, body: jsonEncode(<String, dynamic>{
      'input': query,
      'key': apiKey,
      'type': 'geocode', // 或者 'establishment' 等其他类型
      'components': <String, String>{'country': 'us'}, // 可选的地理限制
      'language': 'en',
    }));

    if (response.statusCode == 200) {
      final data = jsonDecode(response.body) as Map<String, dynamic>;
      final predictions = data['predictions'] as List<dynamic>;
      return predictions.map<Prediction>((json) => Prediction.fromJson(json)).toList();
    } else {
      throw Exception('Failed to fetch suggestions');
    }
  }
}

// Prediction类用于解析从Google Places API返回的数据
class Prediction {
  final String description;
  final String placeId;

  Prediction({required this.description, required this.placeId});

  factory Prediction.fromJson(Map<String, dynamic> json) {
    return Prediction(
      description: json['description'] as String,
      placeId: json['place_id'] as String,
    );
  }
}

注意

  1. 上述代码包含了一个简化的Prediction类,用于解析从Google Places API返回的预测数据。
  2. 在实际应用中,你应该处理API错误和异常,并可能需要添加更多的用户界面元素来增强用户体验。
  3. 请确保你的API密钥安全,不要将其硬编码在客户端应用中。考虑使用更安全的方法来管理API密钥,比如使用Firebase Cloud Functions或Google Cloud Endpoints。
  4. 由于google_places_autocomplete_flutter插件内部已经封装了对Google Places API的调用,因此上面的_fetchSuggestions方法实际上不是必需的,这里只是为了展示如何手动调用API。在实际应用中,你应该直接使用插件提供的功能。

希望这个示例能帮助你理解如何在Flutter应用中使用google_places_autocomplete_flutter插件来实现地点自动完成搜索功能。

回到顶部