有没有办法在 Flutter 中实现 Google 位置自动完成?

ste*_*lis 4 autocomplete dart flutter google-places-autocomplete flutter-layout

我第一次使用 Flutter 来构建移动应用程序,但我发现没有办法在 textEdit 组件中实现自动完成 google 位置。我的目标是在用户输入位置时获得一种列表视图,就像我们在 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)
      });
    });
  }


}
Run Code Online (Sandbox Code Playgroud)

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

CH *_*loa 11

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

\n

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

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

应该_controller是这样的:

\n
var _controller = TextEditingController();\n
Run Code Online (Sandbox Code Playgroud)\n

并且您必须在您的initState()

\n
@override\nvoid initState() {\n  super.initState();\n  _controller.addListener(() {\n    _onChanged();\n  });\n}\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
https://maps.googleapis.com/maps/api/place/autocomplete/json?\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

不要忘记添加会话令牌,这样您的账单才会安全:)

\n
\n

sessiontoken\xe2\x80\x94 一个随机字符串,用于标识用于计费目的的自动完成\n会话。如果自动完成请求中省略此参数,则该请求将单独计费。有关详细信息,请参阅\n定价表。

\n
\n

最后,这是_onChange函数的完整代码:

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

您必须List<dynamic> _placeList = [];在 Widget 的首字母处声明。

\n

额外的好处是,我们如何显示List建议是这样的:

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

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

\n

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

\n

https://github.com/cmailoa/google_places_autocomplete

\n

如需进一步说明,请查看以下链接。

\n

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

\n