前回の記事でご紹介したGoogleMapsですが、初期表示でローマがフォーカスされてしまいます。
現場でこのケースに遭遇した時は「全ての道はローマに通ず」とか言って楽しんでましたが、いざカスタマイズしようとして結構苦労した記憶があります。
ちなみにこれ、今の今まで知らなかったんですが、Xamarin標準のMapsがローマをフォーカスしてしまうらしいですね。
(参考:Summary of Chapter 28. Location and maps)
今回はPrismを利用してMVVMパターンによる暫定解決策(回避策の方が正しいか?)をご紹介します。
※前回のプロジェクトをそのまま使っていきます。
『Xamarin.Forms.GoogleMaps.Bindings』のNugetパッケージ取得
まず『Xamarin.Forms.GoogleMaps』ですが、そのままではMVVMパターンでの実装が不可能です。
※バインディングできません、MVVMパターンにできません。
開発の際は最初愕然としましたが、調べてみたらなんとデータバインディング用のパッケージをリリースしていらっしゃる方がいました。
(参考:Xamarin.Forms.GoogleMaps用のBinding拡張ライブラリをリリースしました)
ということで早速パッケージをインストールしていきます。
作成者の欄を見て頂くと『Xamarin.Forms.GoogleMaps』の開発者である「amay077」さんの名前も載っていますね。
インストール後はAndroidプロジェクトのMainActivityにパッケージの初期化コードを追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
using Android.App; using Android.Content.PM; using Android.OS; using Prism; using Prism.Ioc; namespace SampleAndroid7._1.Droid { [Activity(Label = "SampleAndroid7._1", Icon = "@mipmap/ic_launcher", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)] public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity { protected override void OnCreate(Bundle bundle) { TabLayoutResource = Resource.Layout.Tabbar; ToolbarResource = Resource.Layout.Toolbar; base.OnCreate(bundle); global::Xamarin.Forms.Forms.Init(this, bundle); // 追加したコード Xamarin.FormsGoogleMaps.Init(this, bundle); Xamarin.FormsGoogleMapsBindings.Init(); LoadApplication(new App(new AndroidInitializer())); } } public class AndroidInitializer : IPlatformInitializer { public void RegisterTypes(IContainerRegistry container) { // Register any platform specific implementations } } } |
XAMLのGoogleMapsにビヘイビアを追加
GoogleMapsの表示位置を変更するには「MoveToRegionBehavior」を使用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:maps="clr-namespace:Xamarin.Forms.GoogleMaps;assembly=Xamarin.Forms.GoogleMaps" xmlns:bindings="clr-namespace:Xamarin.Forms.GoogleMaps.Bindings;assembly=Xamarin.Forms.GoogleMaps.Bindings" x:Class="SampleAndroid7._1.Views.MainPage" Title="{Binding Title}"> <maps:Map> <maps:Map.Behaviors> <bindings:MoveToRegionBehavior Request="{Binding MoveToRegionRequest}"/> </maps:Map.Behaviors> </maps:Map> </ContentPage> |
余談ですが、開発当初は「MoveCameraBehavior」が表示位置の変更だろうと思ってかなり苦労した記憶があります。
画面遷移時に表示位置の変更を行う
ここからが今回の記事の本旨になりますが、前述の通りGoogleMapsの初期表示位置はローマになります。
これをどう解決していくか、というところで最初はViewModelのコンストラクタでやっちゃおうかと思ったんですが、そもそも画面が初期化されていない状態ではできないんですよね…。
ということで『Prism』の「OnNavigatedTo」メソッドを利用しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
using Prism.Navigation; using Xamarin.Forms.GoogleMaps; using Xamarin.Forms.GoogleMaps.Bindings; namespace SampleAndroid7._1.ViewModels { public class MainPageViewModel : ViewModelBase { // 表示位置移動用 public MoveToRegionRequest MoveToRegionRequest { get; } = new MoveToRegionRequest(); /// <summary> /// コンストラクタ /// </summary> /// <param name="navigationService"></param> public MainPageViewModel(INavigationService navigationService) : base(navigationService) { Title = "Main Page"; } /// <summary> /// 画面遷移時処理 /// </summary> /// <param name="parameters"></param> public override void OnNavigatedTo(NavigationParameters parameters) { base.OnNavigatedTo(parameters); // 画面遷移後に現在位置へ移動する MoveToCurrentLocation(); } /// <summary> /// 現在位置へ移動するメソッド /// </summary> public void MoveToCurrentLocation() { // TODO:現在地点の座標取得(下記は兵庫県明石市) MoveToRegionRequest.MoveToRegion(new MapSpan(new Position(35.000000d, 135.000000d), 0.3d, 0.3d)); } } } |
「OnNavigatedTo」メソッドの簡単な説明をしておくと、「当該画面遷移時の処理」で「コンストラクタの後に動き」ます。
(参考:Prism for Xamarin.Forms Navigationイベント詳細 NavigationPage編)
実行してみると初期表示位置がローマから兵庫県へと変わりました。
※明石市じゃないことにびっくりしたのは内緒です。
まとめ
『Xamarin.Forms.GoogleMaps』でローマが初期表示されてしまう問題のMVVMパターンによる回避策として
『Prism』の「OnNavigatedTo」メソッドで初期表示位置を変更する。
MVVMパターンでの実装を行うには『Xamarin.Forms.GoogleMaps.Bindings』を利用しましょう。
以上です。
スポンサーリンク