SIN@SAPPOROWORKSの覚書

C#を中心に、夜な夜な試行錯誤したコードの記録です。

Xamarin.Forms ツールバーアイテムによるメニュー

【 Xamarin 記事一覧 】

Xamarin developersのページでも、何故がまとまった記述がないToolbarItemによるメニューについてまとめてみました。

Pageクラスには、 ToolbarItemsというプロパティがあり、これにToolbarItemを追加することで、メニューを表示することができます。


テキストメニュー

Android iOS WindowsPhone
f:id:furuya02:20141013031925p:plain:w200:left f:id:furuya02:20141013031926p:plain:w200:left f:id:furuya02:20141013031928p:plain:w200:left

テキストだけを指定した場合の表示は図のとおりです。
見て分かるように、WindowsPhoneでは、なんらかのアイコンが必須のようです。

public class MainPage : ContentPage {
    public MainPage(){

    ToolbarItems.Add(new ToolbarItem{
        Name="menu1",
        Command = new Command(() => DisplayAlert("Selected", "menu1", "OK"))
    });
    ToolbarItems.Add(new ToolbarItem {Name = "menu2"});
    ToolbarItems.Add(new ToolbarItem {Name = "menu3"});
}

※3個パラメータのDisplayAlertは、最新のXamarin.Formsをインストールすることで利用可能です。

なお、このメニューは、ナビゲーション領域に表示するため、iOS/AndroidではNavigationPageから生成したPageでないと表示できません。

public class App {
    public static Page GetMainPage() {
        return new NavigationPage(new MainPage());
    }
}

表示順序

デフォルトでは、追加した順に左から並べられますが、Priorityで強制的に順番を変更できます。


Android iOS WindowsPhone
f:id:furuya02:20141013032241p:plain:w200:left f:id:furuya02:20141013032242p:plain:w200:left f:id:furuya02:20141013032244p:plain:w200:left

ToolbarItems.Add(new ToolbarItem { Name = "menu1", Priority = 1 });
ToolbarItems.Add(new ToolbarItem { Name = "menu2", Priority = 3 });//2番目と3番目のPriorityを入れ替える
ToolbarItems.Add(new ToolbarItem { Name = "menu3", Priority = 2 });//2番目と3番目のPriorityを入れ替える
ToolbarItems.Add(new ToolbarItem { Name = "menu4", Priority = 4 });

アイコン表示

Iconプロパティに画像(透過画像)を指定して、アイコンを表示できます。
WindowsPhone以外では、サイズの自動調整はされません。図は、左から22、33、44、66ピクセルの画像を使用したものです。

Android iOS WindowsPhone
f:id:furuya02:20141013033121p:plain:w200:left f:id:furuya02:20141013033122p:plain:w200:left f:id:furuya02:20141013033124p:plain:w200:left


ToolbarItems.Add(new ToolbarItem{
   Name = "menu1",
   Icon = "Menu1.png",
   Command = ...
});

イコン画像の配置場所は、通常の画像と同じで、Androidは、Resources/Drawable、iOSは、Resources、WindowsPhoneでは、プロジェクトのrootになります。


表示数

沢山のメニューを追加したとき、表示領域を超えた分は、表示されません。(AndroidiOSでは、省略時の優先順位が違うようです)

Android
f:id:furuya02:20141013033633p:plain:w200:left f:id:furuya02:20141013033635p:plain:w400:left
iOS
f:id:furuya02:20141013033729p:plain:w200:left f:id:furuya02:20141013033731p:plain:w400:left
WindowsPhone
f:id:furuya02:20141013033742p:plain:w200:left f:id:furuya02:20141013033743p:plain:w400:left



for (var i = 0; i < Device.OnPlatform(9,9,4); i++){
     var name = string.Format("Menu{0}",i+1);
     ToolbarItems.Add(new ToolbarItem { Name = name, Icon = name+".png" });
}

WindowsPhoneでは、4個までしか指定できず、5個以上では例外が発生しました。
f:id:furuya02:20141013033411p:plain


表示位置

Orderの指定でメニューの表示領域を変更できます。

ToolbarItems.Add(new ToolbarItem{
    Name = "Menu1",
    Icon = "Menu1.png",
    Order = ToolbarItemOrder.Primary
});
ToolbarItems.Add(new ToolbarItem{
    Name = "Menu2",
    Icon = "Menu2.png",
    Order = ToolbarItemOrder.Secondary
});

Android iOS WindowsPhone
f:id:furuya02:20141013034248p:plain:w200:left f:id:furuya02:20141013034249p:plain:w200:left f:id:furuya02:20141013034251p:plain:w200:left


Android Player では、ToolbarItemOrder.Secondaryでメニューが表示されなくて、ちょっと嵌りました。まだ、プレビューですもんね・・


コマンドの記述方法

選択時のアクションについては、文脈やパラメターの有無などによって最適な記述が選択して下さい。

public MainPage(){

    //Activatedによるイベント処理
    var menu1 = new ToolbarItem { Name = "menu1" };
    menu1.Activated += (s, a) => {
        DisplayAlert("Selected", ((ToolbarItem)s).Name, null, "OK");
    };
    ToolbarItems.Add(menu1);

    //外部メソッドの呼び出し
    var menu2 = new ToolbarItem{
        Name="menu2",
        Command = new Command(Click)
    };
    ToolbarItems.Add(menu2);

    //CommandParameterによるパラメータ渡し
    var menu3 = new ToolbarItem {
        Name = "menu3",
        CommandParameter = "menu3",
        Command = new Command(key =>{
            DisplayAlert("Selected",(string)key, null, "OK");
        })
    };
    ToolbarItems.Add(menu3);

}

void Click(){
    DisplayAlert("Selected","Click", null, "OK");
}

Xaml

最後に、Xamlで記述する場合の例です。

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        x:Class="App2.MainPage">
  <ContentPage.ToolbarItems>
    <ToolbarItem Name="Menu1" Activated="OnClick" Order="Primary" Priority="0" Icon="Menu1.png"/>
    <ToolbarItem Name="Menu2" Activated="OnClick" Order="Primary" Priority="1" Icon="Menu2.png"/>
    <ToolbarItem Name="Menu3" Activated="OnClick" Order="Secondary" Priority="0" Icon="Menu3.png"/>
    <ToolbarItem Name="Menu4" Activated="OnClick" Order="Secondary" Priority="1" Icon="Menu4.png"/>
    <ToolbarItem Name="Menu5" Activated="OnClick" Order="Secondary" Priority="2" Icon="Menu5.png"/>
  </ContentPage.ToolbarItems>
</ContentPage>

イベントの記述は次のとおり

public void OnClick(object sender, EventArgs e) {
    DisplayAlert("Seleted", ((ToolbarItem)sender).Name, "OK");
}

Android iOS WindowsPhone
f:id:furuya02:20141013034508p:plain:w200:left f:id:furuya02:20141013034510p:plain:w200:left f:id:furuya02:20141013034511p:plain:w200:left




[参考にさせて頂いたページ]

Xamarin Forms Navigation Bar Buttons Recipe
http://www.syntaxismyui.com/xamarin-forms-navigation-bar-buttons-recipe/#lightbox/0/

ToolbarItems in Xamarin Forms
http://codeworks.it/blog/?p=232

アイコンジェネレータ
http://romannurik.github.io/AndroidAssetStudio/icons-generic.html#source.type=clipart&source.space.trim=0&source.space.pad=0&source.clipart=res%2Fclipart%2Ficons%2Faction_about.svg&size=44&padding=8&color=33b5e5%2C100&name=ic_action_about


【 Xamarin 記事一覧 】