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

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

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

google_maps_places_autocomplete_widgets 是一个功能完整的 Flutter 插件,提供了地址自动完成功能,可以替代标准的 TextFieldTextFormField。该插件利用 Google Maps Places API 实现地址和邮政编码的自动补全。

特性

  • 支持大多数常见的 TextFieldTextFormField 参数。
  • 支持地址和邮政编码/邮编的自动补全。
  • 提供丰富的回调函数以自定义行为。
  • 易于集成到现有的表单中。
  • 几乎所有外观和行为属性都可以定制。
  • 可以从用户选择的地址填充多个表单字段(城市、州、邮编等)。
  • 在清除按钮被使用时,可以清空多个其他表单字段。

使用示例

引入依赖

首先,在 pubspec.yaml 文件中添加插件依赖:

dependencies:
  google_maps_places_autocomplete_widgets: ^latest_version

然后在 Dart 文件中导入插件:

import 'package:google_maps_places_autocomplete_widgets/address_autocomplete_widgets.dart';

示例代码

以下是一个完整的示例 Demo,展示了如何使用 AddressAutocompleteTextFieldAddressAutocompleteTextFormField

主应用类

import 'package:flutter/material.dart';
import 'package:google_maps_places_autocomplete_widgets/address_autocomplete_widgets.dart';
// 假设你已经有一个包含API密钥的文件 privatekeys.dart
import 'privatekeys.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Google Address AutoComplete Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: DefaultTabController(
        length: 2,
        child: Scaffold(
          appBar: AppBar(
            bottom: const TabBar(
              tabs: [
                Tab(text: 'TextField'),
                Tab(text: 'TextFormField'),
              ],
            ),
            title: const Center(child: Text('Google_Map_Places_AutoComplete_Widgets Demo', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold))),
          ),
          body: const TabBarView(
            children: [
              AddressAutocompleteTextFieldExample(title: 'TextField Example'),
              AddressAutocompleteTextFormFieldExample(),
            ],
          ),
        ),
      ),
    );
  }
}

TextField 示例

class AddressAutocompleteTextFieldExample extends StatefulWidget {
  const AddressAutocompleteTextFieldExample({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  _AddressAutocompleteTextFieldExampleState createState() => _AddressAutocompleteTextFieldExampleState();
}

class _AddressAutocompleteTextFieldExampleState extends State<AddressAutocompleteTextFieldExample> {
  // 省略了状态变量声明...

  void onSuggestionClick(Place placeDetails) {
    setState(() {
      // 更新状态变量...
    });
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Center(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              const Text('Example of address lookup:'),
              SizedBox(
                height: 40,
                child: AddressAutocompleteTextField(
                  mapsApiKey: GOOGLE_MAPS_ACCOUNT_API_KEY,
                  onSuggestionClickGetTextToUseForControl: (placeDetails) => placeDetails.streetAddress,
                  onInitialSuggestionClick: (suggestion) {},
                  onSuggestionClick: onSuggestionClick,
                  hoverColor: Colors.purple,
                  selectionColor: Colors.red,
                  buildItem: (suggestion, index) {
                    return Container(
                      margin: const EdgeInsets.fromLTRB(1, 1, 1, 1),
                      padding: const EdgeInsets.all(8),
                      alignment: Alignment.centerLeft,
                      color: Colors.white,
                      child: Text(suggestion.description)
                    );
                  },
                  clearButton: const Icon(Icons.close),
                  componentCountry: 'us',
                  language: 'en-US',
                  decoration: const InputDecoration(
                    contentPadding: EdgeInsets.all(8),
                    border: OutlineInputBorder(borderSide: BorderSide(color: Colors.white)),
                    hintText: "Address",
                  ),
                ),
              ),
              // 其他UI元素...
            ],
          ),
        ),
      ),
    );
  }
}

TextFormField 示例

class AddressAutocompleteTextFormFieldExample extends StatefulWidget {
  const AddressAutocompleteTextFormFieldExample({Key? key}) : super(key: key);

  @override
  _AddressAutocompleteTextFormFieldExampleState createState() => _AddressAutocompleteTextFormFieldExampleState();
}

class _AddressAutocompleteTextFormFieldExampleState extends State<AddressAutocompleteTextFormFieldExample> {
  final _formKey = GlobalKey<FormState>();
  late FocusNode addressFocusNode;
  late TextEditingController addressTextController;

  @override
  void initState() {
    super.initState();
    addressFocusNode = FocusNode();
    addressTextController = TextEditingController();
  }

  @override
  void dispose() {
    addressFocusNode.dispose();
    addressTextController.dispose();
    super.dispose();
  }

  void onSuggestionClick(Place placeDetails) {
    addressTextController.text = placeDetails.streetAddress ?? '';
  }

  InputDecoration getInputDecoration(String hintText) {
    return InputDecoration(
      filled: true,
      fillColor: Colors.white,
      hintText: hintText,
      hintStyle: const TextStyle(color: Colors.grey),
      focusedBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(10.0),
        borderSide: const BorderSide(color: Colors.purple),
      ),
      enabledBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(10.0),
        borderSide: const BorderSide(color: Colors.black12, width: 1.0),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Center(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Form(
            key: _formKey,
            child: Column(
              children: <Widget>[
                AddressAutocompleteTextFormField(
                  mapsApiKey: GOOGLE_MAPS_ACCOUNT_API_KEY,
                  onSuggestionClickGetTextToUseForControl: (placeDetails) => placeDetails.streetAddress,
                  onSuggestionClick: onSuggestionClick,
                  hoverColor: Colors.purple,
                  selectionColor: Colors.purpleAccent,
                  buildItem: (suggestion, index) {
                    return Container(
                      margin: const EdgeInsets.fromLTRB(2, 2, 2, 2),
                      padding: const EdgeInsets.all(8),
                      alignment: Alignment.centerLeft,
                      color: Colors.white,
                      child: Text(suggestion.description, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.bold))
                    );
                  },
                  clearButton: const Icon(Icons.close),
                  componentCountry: 'us',
                  language: 'en-US',
                  autofocus: true,
                  keyboardType: TextInputType.streetAddress,
                  textCapitalization: TextCapitalization.words,
                  style: const TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
                  decoration: getInputDecoration('Start typing address for Autocomplete..'),
                ),
                // 其他表单项...
              ],
            ),
          ),
        ),
      ),
    );
  }
}

结论

通过以上步骤,你可以轻松地在你的 Flutter 应用中集成 Google 地址自动完成功能。更多详细信息和高级用法请参考 GitHub Repo


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

1 回复

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


当然,以下是一个关于如何在Flutter应用中使用google_maps_places_autocomplete_widgets插件来实现地点搜索自动完成的示例代码。这个插件封装了Google Places API,使得在Flutter应用中实现地点搜索变得相对简单。

首先,你需要在你的pubspec.yaml文件中添加这个插件的依赖:

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

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

接下来,你需要在你的Flutter项目中配置Google Places API的API密钥。这通常涉及到在你的Google Cloud Platform项目中启用Places API,并获取一个API密钥。然后,你需要将这个API密钥安全地存储在你的应用中,通常是通过环境变量的方式(虽然对于Flutter来说,直接在代码中硬编码密钥是不推荐的,这里仅作为示例)。

下面是一个简单的示例,展示如何在Flutter应用中使用google_maps_places_autocomplete_widgets插件:

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

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

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

class PlaceSearchScreen extends StatefulWidget {
  @override
  _PlaceSearchScreenState createState() => _PlaceSearchScreenState();
}

class _PlaceSearchScreenState extends State<PlaceSearchScreen> {
  final TextEditingController _controller = TextEditingController();
  PlacePrediction? _selectedPlace;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Place Search'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            GooglePlacesAutocomplete(
              apiKey: 'YOUR_API_KEY_HERE', // 请替换为你的Google Places API密钥
              onSelected: (Prediction result) {
                setState(() {
                  _selectedPlace = result as PlacePrediction;
                });
              },
              options: AutocompleteOptions(
                mode: Mode.fullscreen,
              ),
            ),
            SizedBox(height: 20),
            if (_selectedPlace != null)
              Text(
                'Selected Place: ${_selectedPlace!.description}',
                style: TextStyle(fontSize: 18),
              ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

在这个示例中,我们创建了一个简单的Flutter应用,它包含一个用于搜索地点的输入框。当用户选择一个地点时,该地点的描述将显示在输入框下方。

请注意,你需要将YOUR_API_KEY_HERE替换为你自己的Google Places API密钥。此外,这个示例使用的是GooglePlacesAutocomplete小部件的默认设置,你可以根据需要调整AutocompleteOptions来定制搜索行为。

确保你已经正确配置了Google Cloud Platform项目,并且你的API密钥具有访问Places API的权限。否则,你将无法成功进行地点搜索。

回到顶部