🤯

FlutterでGoogleMapが開くときに現在地で表示する

2 min read

Flutterでgoogle_maps_flutterを利用してGoogleMapを表示しました。
しかしアプリの初期起動が指定した座標になってしまい、このままだとUX的にどうなのということで、アプリ開いたらユーザーの現在地を中心に表示させます。

なお、ユーザーがアプリに位置情報の利用を許可しなかった場合のことは考えていないのであしからず…
そのうち追記します

まだまだFlutter歴も浅くわからないことだらけだったので、teratailで質問したところ、回答いただけたので、こちらをベースに書いていきます

https://teratail.com/questions/349059

バージョン

flutter --version
Flutter 2.2.1 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 02c026b03c (7 weeks ago) • 2021-05-27 12:24:44 -0700
Engine • revision 0fdb562ac8
Tools • Dart 2.13.1

使用ライブラリ

google_maps_flutter: ^2.0.6
geolocator: ^7.2.0+1

https://pub.dev/packages/google_maps_flutter

https://pub.dev/packages/geolocator

コード

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'dart:async';
import 'package:geolocator/geolocator.dart';

class MapBody extends StatefulWidget {
  
  _MapBody createState() => _MapBody();
}

class _MapBody extends State<MapBody> {
  Completer<GoogleMapController> _controller = Completer();

  late LatLng _initialPosition;
  late bool _loading;

  
  void initState() {
    super.initState();
    _loading = true;
    _getUserLocation();
  }

  void _getUserLocation() async {
    Position position = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.high);
    setState(() {
      _initialPosition = LatLng(position.latitude, position.longitude);
      _loading = false;
      print(position);
    });
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: _loading
          ? CircularProgressIndicator()
          : SafeArea(
              child: Stack(
                fit: StackFit.expand,
                children: [
                  GoogleMap(
                    initialCameraPosition: CameraPosition(
                      target: _initialPosition,
                      zoom: 14.4746,
                    ),
                    onMapCreated: (GoogleMapController controller) {
                      _controller.complete(controller);
                    },
                    // markers: _createMarker(),
                    myLocationEnabled: true,
                    myLocationButtonEnabled: true,
                    mapToolbarEnabled: false,
                    buildingsEnabled: true,
                    onTap: (LatLng latLang) {
                      print('Clicked: $latLang');
                    },
                  ),
                  buildFloatingSearchBar(),
                ],
              ),
            ),
    );
  }
}

ミソは現在地の取得が終わるまで、_loadingを挟むことによって画面描画時にロード画面を表示させるということです。

これがないと、現在地の取得の前に画面の描画をしてしまい、エラーが出ます。