有没有办法在 Flutter 中实现 Google Places 自动补全?

问题描述 投票:0回答:3

我第一次使用 Flutter 来构建移动应用程序,但我发现没有办法在文本编辑组件中实现自动完成谷歌地点。我的目标是在用户输入位置时获得一种列表视图,就像我们在 Android/iOS 本机实现和 React/ionic 中所做的那样。

我获得的是一个 TextEdit 组件,它搜索可能的位置并在最后获取第一个位置。这是我的代码片段

class HomeFragmentState extends State<HomeFragment>{

  GoogleMapController mapController;
  String searchAddr;
  List<Marker> markersList = [];
  Marker finalMarker;
  LatLng _center = LatLng(45.4654219,9.1859243);  // default location

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: <Widget>[
          GoogleMap(
              onMapCreated: onMapCreated,
              initialCameraPosition: CameraPosition(
              target: _center,
              zoom: 11.0,
            ),
            markers: Set.from(markersList),
          ),
          Positioned(
            top: 10.0,
            right: 15.0,
            left: 15.0,
            child: Container(
                  height: 50.0,
                  width: double.infinity,
                  decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(10.0),
                      color: Colors.white
                  ),
                  child: Column(
                    children: <Widget>[
                      TextField(
                        decoration: InputDecoration(
                            hintText: 'Enter the place',
                            border: InputBorder.none,
                            contentPadding: EdgeInsets.only(left: 15.0,top:15.0),
                            suffixIcon: IconButton(
                              icon: Icon(Icons.search),
                              onPressed: searchAndNavigate,
                              iconSize: 30.0,
                            )
                        ),
                        onChanged: (val) {
                          setState(() {
                            searchAddr = val;
                          });
                        },
                        onEditingComplete: searchAndNavigate,
                      ),
                    ],
                  )
                ),
          ),
        ],
      ),
    );
  }

  void searchAndNavigate(){
    Geolocator().placemarkFromAddress(searchAddr).then((result) => {navigateTo(result:result)});
  }


  navigateTo({result, init: false}){
    var zoom = 11.0;
    var target;
    if(init){
      zoom = 12.0; //difference between searching and initializing
      target = LatLng(result.latitude, result.longitude);
    } else {
      target = LatLng(result[0].position.latitude,result[0].position.longitude);
    }
    mapController.animateCamera(CameraUpdate.newCameraPosition(CameraPosition(
        target:target,
        zoom: zoom
    )));
  }

  void onMapCreated(controller){
    setState(() {
      mapController = controller;
      Geolocator().getCurrentPosition(desiredAccuracy: LocationAccuracy.high).then((position) => {
        navigateTo(result: position,init: true)
      });
    });
  }


}

正如我们从地理定位器中看到的,我们可以根据我们输入的地址检索某些位置(因此我们可以从那里获取结果),但我没有找到一种明智的方法来实现文本编辑建议部分

flutter dart autocomplete flutter-layout google-places-autocomplete
3个回答
11
投票

我和你有同样的问题。实际上 google 自动完成可以通过基本的 HTTP API 请求来完成。我已经创建了一些关于它的文章,名为“你自己的 - Flutter Google Places Autocomplete”。

我已经通过基本的异步 HTTP 请求完成了此操作。 首先,您必须设置一个控制器并在 TextField 初始化时放置侦听器

TextField(
  controller: _controller,
  decoration: InputDecoration(
    hintText: "Seek your location here",
    focusColor: Colors.white,
    floatingLabelBehavior: FloatingLabelBehavior.never,
    prefixIcon: Icon(Icons.map),
    suffixIcon: IconButton(
      icon: Icon(Icons.cancel),
    ),
  ),
),

_controller
应该是这样的:

var _controller = TextEditingController();

并且您必须在您的

initState()

注册一个监听器
@override
void initState() {
  super.initState();
  _controller.addListener(() {
    _onChanged();
  });
}

_onChange
函数可以定义为异步函数来调用Google提供的
Google Places Autocomplete
标准API请求

https://maps.googleapis.com/maps/api/place/autocomplete/json?

请参阅此链接以更好地了解 Google 地点自动完成功能。

不要忘记添加会话令牌,以便您的账单安全:)

sessiontoken
— 标识自动完成的随机字符串 用于计费目的的会话。如果这个参数被省略 自动完成请求,该请求独立计费。请参阅 详细价格表。

最后,这是

_onChange
函数的完整代码:

_onChanged() {
  if (_sessionToken == null) {
    setState(() {
      _sessionToken = uuid.v4();
    });
  }
  getSuggestion(_controller.text);
}

void getSuggestion(String input) async {
  String kPLACES_API_KEY = "CHANGE THIS WITH YOUR GOOGLE API KEY";
  String type = '(regions)';
  String baseURL =
      'https://maps.googleapis.com/maps/api/place/autocomplete/json';
  String request =
      '$baseURL?input=$input&key=$kPLACES_API_KEY&sessiontoken=$_sessionToken';
  var response = await http.get(request);
  if (response.statusCode == 200) {
    setState(() {
      _placeList = json.decode(response.body)['predictions'];
    });
  } else {
    throw Exception('Failed to load predictions');
  }
}

您必须在 Widget 的首字母处声明

List<dynamic> _placeList = [];

还有额外的好处,我们如何显示建议的

List
是这样的:

ListView.builder(
  physics: NeverScrollableScrollPhysics(),
  shrinkWrap: true,
  itemCount: _placeList.length,
  itemBuilder: (context, index) {
    return ListTile(
      title: Text(_placeList[index]["description"]),
    );
  },
),

将其放在您的 TextField 小部件下。

要获取工作代码,请参考下面的 github 链接(自行添加包!):

https://github.com/cmailoa/google_places_autocomplete

欲了解更多说明,请查看以下链接。

https://link.medium.com/7fq2hr2WZ9


0
投票

Google 为 flutter 放置了自动完成小部件。


  • 依赖关系: 扑: sdk:颤动 flutter_google_places_hoc081098:^1.0.0-nullsafety.4

Future<void> _handlePressButton() async {
// show input autocomplete with selected mode
// then get the Prediction selected
Prediction? prediction = await PlacesAutocomplete.show(
    context: context,
    apiKey: kGoogleApiKey,
    onError: onError,
    mode: Mode.fullscreen,
  // Mode.overlay
  //language: "en",
  //components: [Component(Component.country, "in")]
);

    displayPrediction(prediction);
 }



 void onError(PlacesAutocompleteResponse response) {
homeScaffoldKey.currentState!.showSnackBar(
  SnackBar(content: Text(response.errorMessage!)),
);}

欲了解更多信息...


0
投票

请使用 onChanged 而不是监听器。

© www.soinside.com 2019 - 2024. All rights reserved.