[Xamarin.Forms] 地図にピンを表示する(Xamarin.Forms.Maps編)

Xamarin.Forms.MapsのMapクラスには、Pinsというピン専用のプロパティがあり、Addメソッドを使用してピンを立てることができます。

AddメソッドにはPinクラスのインスタンスを渡します。

このPinクラスには、以下表に示す設定を行うことができます。

Type ピンの種類。Generic, Place, SavedPin, SearchResultのいずれかを指定します。
Position 地図上のピンの表示位置を指定します。
Label ピンに表示するラベルの文字列を指定します。
Address ピンに表示する住所を表す文字を指定します

以下に、2つのピンを表示するコード例を示します。

// 以下追加
using Xamarin.Forms;
using Xamarin.Forms.Maps;
namespace MapSample
{
    public class MapPage : ContentPage
    {
        public MapPage()
        {
            var map = new Map(
                MapSpan.FromCenterAndRadius(
                    new Position(35.6329, 139.8803),
                    Distance.FromKilometers(1.0))) {
                IsShowingUser = true,
                VerticalOptions = LayoutOptions.FillAndExpand,
                HasScrollEnabled = true,
                HasZoomEnabled = false
                    
                                               
            };

            // 1つ目のピンを作成
			var pin1 = new Pin
			{
				Type = PinType.Place,
				Position = new Position(35.6329, 139.8803), 
				Label = "ねずみ〜らんど",
				Address = "夢と魔法の国"
			};
            // Mapに1つ目のピン追加
			map.Pins.Add(pin1);

            // 2つ目のピンを作成
			var pin2 = new Pin
			{
				Type = PinType.Place,
				Position = new Position(35.6267, 139.8850),
				Label = "ねずみ〜し〜",
				Address = "俺の国建設予定地"
			};
            // Mapに2つ目のピンを追加
			map.Pins.Add(pin2);
           
			Content = new StackLayout
            {
                Children = { map }
            };
        }
    }
}

22〜31行目で1つ目のピンを、33〜42行目で2つ目のピンを追加しています。

[Xamarin.Forms] 地図の初期化を理解する(Xamarin.Forms.Maps編)

前回の記事で、地図の表示を行いました。

今回は、地図表示時の初期化コードを掘り下げて見ていきます。

はじめに前回のコードをおさらいしましょう。

using System;

// 以下追加
using Xamarin.Forms;
using Xamarin.Forms.Maps;
namespace MapSample
{
    public class MapPage : ContentPage
    {
        public MapPage()
        {
            var map = new Map(
                MapSpan.FromCenterAndRadius(
                    new Position(35.6329, 139.8803),
                    Distance.FromMiles(0.0))) {
                IsShowingUser = true,
                VerticalOptions = LayoutOptions.FillAndExpand
            };
            Content = new StackLayout
            {
                Children = { map }
            };
        }
    }
}

12行目〜18行目の部分に注目してみましょう。

12行目のnew Mapは、Xamarin.Froms.Map を使用するための初期化コードです。正確にはMapのインスタンスを作成している部分です。

引数に渡しているMapSpan.FromCenterAndRadius(13行目)は、マップ表示時に画面の中央の位置をどこにするかと、表示する半径の距離を設定するものです。

14行目のnew Position()が画面中央の緯度と経度を表します。緯度と経度ともに10進法で指定する必要があります。60進法の指定ではないので注意して下さい。第1引数に緯度を第2引数に経度を指定します。なお、英語で緯度は「Latitude」、経度は「longitude」と言うので、覚えておくと海外サイトの記事も読みやすくなります。

続く15行目のDistance.FromMilesは、画面の中心から半径何マイルを表示するかを設定するものです。FromMilesとなっているので、単位はマイルになります。日本人になじみがあるのはKmなので、 FromKilometersを使用するとよいでしょう。

16行目のIsShowIngUserは、デバイスの現在位置を地図上に表示するかを指定するものです。trueを指定すると、地図上にデバイスの位置を表すマークが表示されるようになります。

17行目のVerticalOptionsは垂直方向の表示オプションです。FillAndExpandを指定しているので、画面いっぱいに表示されます。

これ以外にも指定可能なオプションがあるので紹介します。

HasScrollEnabledは、スクロールを許可するかどうかを指定します。falseを指定するとマップをスクロールして表示することができません。既定値はtrueです。

HasZoomEnabledは、マップの拡大縮小を許可するかどうかを指定します。falseを指定すると、拡大縮小ができなくなります。既定値はtrueです。

以上のオプションを使用して、好みに合った地図が表示されるようにしましょう。

 

[Xamarin.Forms] 地図を表示する(Xamarin.Forms.Maps編)

今回は、Xamarin.Formsで地図を表示する方法を見ていきたいと思います。

使用した環境は Visual Studio for Mac Preview版で、参考にしたサイトは http://www.buildinsider.net/mobile/xamarintips/0039 です。

はじめにプロジェクトの作成をします。

VS for Macでは、[Multiplatform]-[アプリ]を選択し、一覧から「Blank Forms App」を選択します。

続いてApp NameとOrganization Identifierを入力します。

App Nameにはアプリケーション名を、Organization Identifierは、一般的にドメインを逆に入力した文字列を入力します。私の場合は hiros-dot.net というドメインを持っているので「net.hiros-dot」と入力しています。

続いて、プロジェクト名、ソリューション名、ファイル一式を格納する場所を入力します。

とりあえず以上でプロジェクトの作成は完了です。

次にXamrin.Formsで使用可能な地図表示ライブラリ(Xamarin.Forms.Maps)をNuGetから取得します。

メニューの[プロジェクト]-[NuGetパッケージの追加]を選択します。

「パッケージを追加」というダイアログが表示されるので、右上の検索窓で「Xamarin.Forms.Maps」と入力して[Enter]キーを押します。

一覧で「Xamarin.Forms.Maps」にチェックを付けて、右下の[パッケージを追加]ボタンをクリックします。

パッケージの追加が完了したら、参照フォルダを展開してみて下さい。

追加した、Xamarin.Forms.Mapsが追加されていることを確認できます。

さて、いよいよ本題へと移ります。

画面に表示するページを作成します。

「iOS」も「Droid」も付いていないプロジェクトの下にMapPageという名前の新規クラスファイル(MapPage.cs)を作成します。

このMapPageはContentPageクラスを継承して作成します。

using System;

// 以下追加
using Xamarin.Forms;
using Xamarin.Forms.Maps;
namespace MapSample
{
    public class MapPage : ContentPage
    {
        public MapPage()
        {
            var map = new Map(
                MapSpan.FromCenterAndRadius(
                    new Position(35.6329, 139.8803),
                    Distance.FromMiles(0.0))) {
                IsShowingUser = true,
                VerticalOptions = LayoutOptions.FillAndExpand
            };
	    Content = new StackLayout
            {
                Children = { map }
            };
        }
    }
}

参考にしたサイトのコードをそのまま拝借し、new Position と記載している箇所の引数の値を変更しています。この例ではディズニーランドを指しています。

続いて、App.xaml.cs ファイルを以下のように編集します。

using Xamarin.Forms;

namespace MapSample
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();

            MainPage = new MapPage(); 
        }

        protected override void OnStart()
        {
            // Handle when your app starts
        }

        protected override void OnSleep()
        {
            // Handle when your app sleeps
        }

        protected override void OnResume()
        {
            // Handle when your app resumes
        }
    }
}

App() コンストラクタ内では、先ほど作成したMapPageのインスタンスをMainPageに代入するようにしています。

以上で実行すると、以下のように地図が表示されます。

[Xamarin][CrossPlatform][Control] ListView

ListViewはDatePickerやTimePickerのような外観を持つコントロールで、複数の値から任意の値を選択することができます。

ListViewには任意の複数の値を表示することができます。

以下はListViewとその下にLabelコントロールを配置するXAMLの例です。

<StackLayout Margin="10,30,10,10">
  <ListView x:Name="lsvItems" SeparatorColor="Fuchsia"/>
  <Label x:Name="lblItem" />
</StackLayout>

以下は、ListViewに大吉、中吉、小吉という文字を表示し、選択された文字をLabelに表示する例です。

ListViewに表示する項目はItemSourceプロパティで設定することができます。項目が選択されるとItemSelectedというイベントが発生します。選択された項目はSelectedItemで取得することができます。

public ListViewSample3Page()
{
	InitializeComponent();

	string[] strItems = new string[] { "大吉", "中吉", "小吉" };

	// ListViewに表示する選択肢を設定
	lsvItems.ItemsSource = strItems;

	// ListViewでアイテムが洗濯されたときの処理
	lsvItems.ItemSelected += (sender, e) => {
		// 選択された値をラベルに表示
		lblItem.Text = lsvItems.SelectedItem.ToString();
	};
}

実行例を以下に示します。

[Xamarin][CrossPlatform][Control] WebView

WebViewコントロールを使用すると、Webブラウザを実装することができます。

WebViewコントロールに表示するページ(URL)は、Sourceプロパティで指定します。

戻れるページがあるかどうかはCanGoBackプロパティ、進めるページがあるかどうかはCanGoForwardプロパティがTrueかどうかを確認します。

以下はWebViewコントロールを配置するXAMLの例です。

一番上にはSearchBarコントロール、次にWebViewコントロール、一番下にButtonコントロールを2つ(戻る、進む)配置しています。

[<]ボタンはWebViewのCanGoBackプロパティと、[>]はCanGoForwadプロパティをバインディングし、戻るページがある場合と、進むページがある場合に押せるようになります。

<StackLayout Margin="10,30,10,10">
  <SearchBar x:Name="searchBar" Placeholder="Enter url" />
  <WebView x:Name="webView" 
    VerticalOptions="FillAndExpand"
    Source="https://www.xamarin.com/" />

  <StackLayout Orientation="Horizontal" 
    BindingContext="{x:Reference webView}">
    <Button x:Name="btnBack" Text="&lt;" 
      IsEnabled="{Binding CanGoBack}" />
    <Button x:Name="btnForawd" Text="&gt;" 
      IsEnabled="{Binding CanGoForward}" />
  </StackLayout>
</StackLayout>

次に、それぞれのイベントを使用する例をみていきましょう。

検索用の入力エリアではSearchBarのボタンが押されたときのイベントで、入力されたURLへ移動できるようにしています。入力されたURLはWebViewコントロールのSourceプロパティに設定します。

ページが遷移するときは、Navigatingというイベントが発生します。ページ遷移中はSearchBarコントロールが使用できないようにIsEnabledプロパティにfalseを設定しています。ページ遷移が完了したときはNavigatedイベントが発生するのでIsEnabledイベントにtrueを設定して再び使用できるようにしています。

[<]ボタンがクリックされたときは、WebViewコントロールのGoBack()メソッドを実行し、[>]ボタンが句陸されたときはGoForward()メソッドを実行するようにしています。

public MainPage()
{
  InitializeComponent();

  // [検索]ボタンタップ時の処理
  searchBar.SearchButtonPressed += (sender, e) =>
  {
    // 指定されたURLを開く
    webView.Source = searchBar.Text;
  };

  // ページ遷移中の処理
  webView.Navigating += (sender, e) =>
  {
    searchBar.IsEnabled = false;  
  };

  // ページ遷移完了時の処理
  webView.Navigated += (sender, e) =>
  {
    searchBar.IsEnabled = true;
  };

  // [<]ボタンクリック時の処理
  btnBack.Clicked += (sender, e) =>
  {
    webView.GoBack();
  };

  // [>]ボタンクリック時の処理
  btnForawd.Clicked += (sender, e) =>
  {
    webView.GoForward();
  };
}