Flutter×GoogleMap基礎編④〜タップやカメラの動きを検知する〜

プログラミング

はじめに

今回はFlutterアプリケーションにGoogleMapを組み込むためのパッケージである、
google_maps_flutterの使い方をご紹介します。

これまでの基礎編①〜③では、マーカーやポリゴンなどのオブジェクトを
GoogleMap()ウィジェットに表示する方法について解説しました。

今回の基礎編④では、タップやマップを動かした時のイベントを検知して
処理を実行する方法をご紹介します。

基礎編①〜③をご覧になりたい方は下記からご参照ください。

実装していく

今回使用するgoogle_maps_flutterのバージョンは下記です。

dependencies:
  google_maps_flutter: ^2.1.4

 

ベースのプログラム

まずはmain.dartにベースとなるプログラムを作成します。
サンプルコードをコピペで貼り付けて実行するとマーカーが1つ描画されたGoogleMapが表示されます。
これらは全て基本編①〜③で学んできた内容です。

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

void main() {
  runApp(MaterialApp(home: Map()));
}

class Map extends StatefulWidget {
  const Map({Key? key}) : super(key: key);
  @override
  State<Map> createState() => _MapState();
}

class _MapState extends State<Map> {
  static final CameraPosition _cameraPosition = CameraPosition(target: LatLng(35, 135), zoom: 15);
  LatLng _location = LatLng(35, 135);

  // 位置情報とマーカーIDを指定してマーカーを表示する関数
  Set<Marker> _createMarker(LatLng latLng, String markerId) {
    return { Marker(markerId: MarkerId(markerId),position: latLng,),};
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GoogleMap(
        initialCameraPosition: _cameraPosition,
        markers: _createMarker(_location, 'marker_1'),
      ),
    );
  }
}
  • _createMarker()メソッド
    自作関数です。位置情報LatLngとマーカーIDを受け取り、Set<Marker>型を返す関数です。
  • _cameraPosition定数
    初期カメラ位置を定数で宣言しています。
  • _location
    マーカーの表示位置を変数で宣言しています。(初期値は_cameraPosition定数と同じにしています。)

タップ検知

ノーマルタップ onTap()

GoogleMapがタップされたことを検知するためには、
GoogleMap()ウィジェットのonTap()メソッドを使用します。
今回はタップした箇所にマーカーを立てるようにしたいと思います。
※サンプルコードはGoogleMap()ウィジェット部分のみ抜粋していますので、前章のベースコードを修正する形でご確認ください。

GoogleMap(
        initialCameraPosition: _cameraPosition,
        markers: _createMarker(_location, 'marker_1'),
        onTap: (LatLng latLang) {
          setState(() {
            _createMarker(_location = latLang, 'marker_1');
          });
        },
      ),
  • onTap()メソッド
    マップがタップされた時の処理を記述します。
    タップされた箇所の位置情報(経度緯度)がLatLng型でコールバックされますので、
    今回はその位置情報をもとにsetState()でマーカーを再生成しています。

基本編③のcirclesプロパティと組み合わせると下記のようになります。
(Circle()ウィジェットのcenterプロパティに_location変数を指定)

長押し onLongPress

長押しの検知にはonLongPress()メソッドで指定します。

GoogleMap(
        initialCameraPosition: _cameraPosition,
        markers: _createMarker(_location, 'marker_1'),
        onLongPress: (LatLng latLang) {
          setState(() {
            _createMarker(_location = latLang, 'marker_1');
          });
        },
      ),

onTap()onLongPress()に変更したのみです。
同様にタップされた位置情報がコールバックされます。

カメラの動きを検知する

GoogleMap()ウィジェットではマップを動かした(=カメラを動かした)ことを検知することができます。
今回の例では下記のような機能を実装します。

  • カメラが動き始めたらボタンを非表示
  • カメラが止まったらボタンを表示

動き始めを検知する onCameraMoveStarted()

画面右下の現在地ボタンに注目してください。
カメラが動き始めた時に非表示になります。

// クラス変数として  bool _buttonVisible = true; を宣言しておく
// _buttonVisibleは現在地ボタンを表示する(true)か非表示にする(false)状態変数。
GoogleMap(
        myLocationButtonEnabled: _buttonVisible, // 現在地ボタンのパラメータ
        initialCameraPosition: _cameraPosition,
        markers: _createMarker(_location, 'marker_1'),
        onCameraMoveStarted: () {
          setState(() {
            _buttonVisible = false;
          });
        },
      ),
  • myLocationButtonEnabledプロパティ
    GoogleMap()ウィジェットのプロパティの1つ。
    trueの場合、画面右下の現在地ボタンが表示され、falseの場合非表示になります。
    例では_buttonVisible変数で切り替えるようにしています。
    クラス変数として「bool _buttonVisible = true;」を定義しておく必要があります。
  • onCameraMoveStarted()メソッド
    カメラが動き出した時に実行されます。setState()で_buttonVisibleをfalseにすることで現在地ボタンが非表示になります。

止まった時を検知する onCameraIdle()

カメラが止まったことを検知するためにはonCameraIdle()メソッドを使います。
先程の例と合わせた結果が下記です。

止まった時に現在地ボタンが再表示されているのがわかるかと思います。

// クラス変数として  bool _buttonVisible = true; を宣言しておく
// _buttonVisibleは現在地ボタンを表示する(true)か非表示にする(false)状態変数。
GoogleMap(
        myLocationButtonEnabled: _buttonVisible, // 現在地ボタンのパラメータ
        initialCameraPosition: _cameraPosition,
        markers: _createMarker(_location, 'marker_1'),
        onCameraMoveStarted: () {
          setState(() {
            _buttonVisible = false;
          });
        },
        onCameraIdle: () async { // 追加
          setState(() {
            _buttonVisible = true;
          });
        }     
    ),
  • onCameraIdle()メソッド
    カメラが止まった時に実行されます。例では現在地ボタンを再表示するため、_buttonVisibleをsetState()でtrueに更新しています。

カメラが動いている間を検知するには?
onCameraMove()メソッドでハンドリングできますが、カメラが動いているあいだ、毎フレームごとにメソッド内の処理が実行されることになります。そのため状態(ウィジェット)の更新など重たい処理には使用しないことをお勧めします。

おわりに

google_maps_flutterパッケージの使い方の中でも今回は
タップやカメラの動きを検知する方法をご紹介いたしました。

次回最終回の基礎編⑤はコントローラからマップを更新する方法について書きたいと思います。

タイトルとURLをコピーしました