前回の記事でご紹介した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にパッケージの初期化コードを追加します。
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」を使用します。
<?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」メソッドを利用しました。
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』を利用しましょう。
以上です。
スポンサーリンク