AIR for Android オプションメニューの作成

2011.09.15

AIR for Androidでのオプションメニューの作成について調べたので、サンプルソースと共にご紹介します。
尚、今回のサンプルは、Flex SDK4.5.1、AIR Runtime2.6で動作確認をしたものです。

オプションメニューの表示

初めにオプションメニューを表示させるにはどうすれば良いかを説明します。
サンプルでは、新規FlexモバイルAIRプロジェクトをアプリケーションテンプレート[ ビューベースアプリケーション ](中央)で作成しました。
プロジェクト名は「test_menu」です。

  • ViewNavigatorApplicationクラスのtest_menu.mxmlは、デフォルトで作成されたままです。
  • firstViewで、デフォルトで作成されるViewクラス[ views.test_menuHomeView ]が指定されています。
  • 		<?xml version="1.0" encoding="utf-8"?>
    			<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                            				xmlns:s="library://ns.adobe.com/flex/spark" 
                            				firstView="views.test_menuHomeView" >
    			</s:ViewNavigatorApplication>
    
    
  • views.test_menuHomeView.mxmlに、オプションメニューの内容を追加します。
  • ViewクラスのviewMenuItemsプロパティに、作成したいメニューの数だけ、ViewMenuItemクラスを追加します。
  • 		<?xml version="1.0" encoding="utf-8"?>
    		<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
    		        xmlns:s="library://ns.adobe.com/flex/spark" 
    		        title="HomeView">
    		    
    		    <s:viewMenuItems>
    		        <s:ViewMenuItem label="Seach" />
    		        <s:ViewMenuItem label="Add" />
    		        <s:ViewMenuItem label="Setting" />
    		        <s:ViewMenuItem label="Refresh" />
    		        <s:ViewMenuItem label="Forward" />
    		    </s:viewMenuItems>
    		</s:View>
    
    

以上で、オプションメニューの作成は完了です。とても簡単ですね。実行すると、下のように表示されます。

デフォルトオプションメニュー

ViewMenuItemクラスは、ButtonBaseクラスを継承しているので、Buttonクラスと同じようにアイコンの追加やイベントハンドラの追加をすることができます。

レイアウト・スタイルの変更

デフォルトのオプションメニューでは最大3列メニューが並びますが、この列数を変更したりスタイルを変更したい時にはどうすれば良いのか調べました。

  • ViewMenuコンテナのスキンクラスを作成します。
    デフォルトのスキンspark.skins.mobile.ViewMenuSkinクラスがコピーされます。
  • レイアウトを変更するには、ViewMenuLayoutcontentGroupLayoutのプロパティを変更します。
    最大列数の設定はrequestedMaxColumnCountで可能です。
  • <s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" 
                 xmlns:fb="http://ns.adobe.com/flashbuilder/2009" alpha.disabled="0.5">
        
        <fx:Metadata>
            <![CDATA[ 
            /** 
            * @copy spark.skins.spark.ApplicationSkin#hostComponent
            */
            [HostComponent("spark.components.ViewMenu")]
            ]]>
        </fx:Metadata> 
              :
            <!--- @copy spark.components.SkinnableContainer#contentGroup -->
            <s:Group id="contentGroup" left="0" right="0" top="3" bottom="2" minWidth="0" minHeight="0">
                <s:layout>
                    <s:ViewMenuLayout id="contentGroupLayout"
                                      horizontalGap="2" 
                                      verticalGap="2"                                   
                                      requestedMaxColumnCount="2" 
                                      requestedMaxColumnCount.landscapeGroup="6"/>
                </s:layout>
            </s:Group>    
    
    
  • 境界線の色と背景色も変更してみます。
  • :
        <s:Group id="chromeGroup"
                 left="0"
                 right="0"
                 top.closedGroup="{hostComponent.height - chromeGroup.height / 2}"
                 bottom.openedGroup="0" 
                 visible.closedGroup="false">
            
            <!-- Divider line -->
            <s:Rect left="0" right="0" top="1" height="0">
                <s:stroke>
                    <s:SolidColorStroke id="dividerStroke" weight="1" color="#800000" alpha=".9"/>   
                </s:stroke>
            </s:Rect> 
            
            <!-- Background -->
            <s:Rect left="0" right="0" top="0" bottom="0" id="background">
                <s:fill> 
                    <s:SolidColor color="#E9967A" alpha="1.0" />
                </s:fill>
            </s:Rect>
              :
    
  • 作成したスキンクラスを適用します。
  • <?xml version="1.0" encoding="utf-8"?>
    <s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                                xmlns:s="library://ns.adobe.com/flex/spark" 
                                firstView="views.test_menuHomeView">
        
        <fx:Style>
             @namespace s "library://ns.adobe.com/flex/spark";
            
            s|ViewMenu {
                skinClass: ClassReference("views.CustomViewMenuSkin")
            }
             
        </fx:Style>
             :
    

実行した結果です。最大列数が2になり、境界線の色と背景色が変更されました。

レイアウトスタイルの変更

任意のタイミングでの表示

オプションメニューは、メニューボタンを押された時に表示されますが、任意のタイミングで表示したいこともあるかもしれません。
こちらも簡単に実現できます。

  • views.test_menuHomeViewにボタンを追加して、そのボタンを押した時にオプションメニューを表示させます。
  • views.test_menuHomeView.mxmlにボタンと、clickイベントハンドラを追加します。
  • イベントハンドラで、ViewNavigatorApplicationBaseクラスのviewMenuOpenにtrueをセットします。
  • 		<?xml version="1.0" encoding="utf-8"?>
    		<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
    		        xmlns:s="library://ns.adobe.com/flex/spark" 
    				title="HomeView">
    					:
    		    <fx:Script>
    		    <![CDATA[
    		        
    		        protected function button1_clickHandler(event:MouseEvent):void {
    		            parentApplication.viewMenuOpen = true;
    		
    		        }
    		    ]]>
    		    </fx:Script>
    					:
    		    <s:Button x="98" y="61" label="オプションメニューの表示" click="button1_clickHandler(event)" />
    		</s:View>
    
    

以上です。これで、ボタンを押した時にもメニューボタンを押した時と同様にオプションメニューが表示されるようになります。

オリジナルのメニューの表示

オプションメニューをレイアウトやスタイルだけでなく、自由にカスタマイズしたいこともあると思います。
メニューボタンを押された時に、任意のビューを表示する方法を説明します。

  • メニューボタンを押した時のイベントハンドラViewNavigatorApplicationBaseクラスのmenuKeyUpHandlerをオーバーライドします。
  • 作成した任意のビュー(ここでは、CustomMenuView)を表示する処理を追加します。
  • set viewMenuOpenも同様にオーバーライドした方が良いでしょう。
  • 		<?xml version="1.0" encoding="utf-8"?>
    		<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
    									xmlns:s="library://ns.adobe.com/flex/spark" 
    									firstView="views.test_menuHomeView">
    		    <fx:Script>
    		    <![CDATA[
    		        import mx.managers.PopUpManager;				        
    		        import views.CustomMenuView;
    							        
    		        private var _menuView:CustomMenuView;
    		        
    		        override protected function menuKeyUpHandler(event:KeyboardEvent):void {
    		            _menuView = PopUpManager.createPopUp(this, CustomMenuView) as CustomMenuView;
    		        }
    		
    		        override public function set viewMenuOpen(value:Boolean):void {
    		            if (value == viewMenuOpen)
    		                return;
    		                        
    		            if (value)
    		                _menuView = PopUpManager.createPopUp(this, CustomMenuView) as CustomMenuView;
    		            else
    		                PopUpManager.removePopUp(_menuView);
    		        }
    		
    		    ]]>
    		    </fx:Script>				
    		</s:ViewNavigatorApplication>
    
    

実行した結果は下の通りです。
メニューボタンを押された時、ViewNavigatorApplicationBase#viewMenuOpenをtrueにした時に、オリジナルのビューを表示します。

カスタムメニュー

以上です。AIR for Androidでのオプションメニューの作成はとても簡単にできることが分かりました。