2015年3月1日日曜日

Titanium Studioでandroidのmenuを動的に変更する

Titanium Studioでアプリケーションを作成していると、ログイン/ログアウトボタンのように、動的にメニューを変更したくなる時があります。 そこで、android用のmenuを動的に変更する方法について、メモを作成しました。 なお、サンプルプロジェクトを以下に保存してあります。必要な方はご利用ください。
https://github.com/ccat/dynamic_menu

まず、メニューは動的に生成することもできますが、今回は始めにAlloyで生成した後、表示・非表示を切り替えることで動的に見た目を変更することにしました。viewのソースコードは下記の通りです。

<Alloy>
  <Window id="index" class="container">
    <Menu platform="android">
      <MenuItem id="menu1" itemId="1" title="Menu1" onClick="menu1func"  />
      <MenuItem id="menu2" itemId="2" title="Menu2" onClick="menu2func" />
    </Menu>
    <Label id="label" >Hello, World</Label>
  </Window>
</Alloy>

真ん中に存在する2つのMenuItemが、今回動的に見た目を切り替えるメニューです。Menu1を選択するとMenu1が非表示になってMenu2が表示され、Menu2を選択するとMenu2が非表示になってMenu1が表示されるようにします。
controllerからはitemIdで操作するため、忘れずにitemIdを設定するようにしてください。また、この時itemIdには整数を指定するようにしてください。整数を指定しない場合、以下のようなエラーが発生します。

[ERROR] :  TiApplication: (main) [27564,27843] Sending event: exception on thread: main msg:java.lang.NumberFormatException: Invalid int: "a1"; Titanium 3.5.0,2015/01/12 15:33,0014f83 
[ERROR] :  TiApplication: java.lang.NumberFormatException: Invalid int: "a1"

次に、controllerは下記のように記載します。


var menu1 = null;
var menu2 = null;
var menu1show=true;

function menu1func(e){
  menu1show=false;
  menuChange();
}

function menu2func(e){
  menu1show=true;
  menuChange();
}

function menuChange(){
  if(menu1!=null){
    menu1.setVisible(menu1show);
  }
  if(menu2!=null){
    menu2.setVisible(!menu1show);
  }
}

var activity=$.index.activity;
activity.onPrepareOptionsMenu = function(e) {
  var menu = e.menu;
  menu1 = menu.findItem("1");
  menu2 = menu.findItem("2");
  menuChange();
};


$.index.open();

まず「activity.onPrepareOptionsMenu」でメニューの各アイテムを取得し、各メニューが選択されるたびに表示を切り替えるようにしています。

「onPrepareOptionsMenu」は、メニューを表示する前に複数回呼び出されるため、メニューの作成をここで行う場合、同じメニューを何回も作成してしまわないように注意してください。
「onCreateOptionsMenu」の場合、1回だけ呼び出される関数なようなのですが、私の環境では1回も呼び出されなかったため、「onPrepareOptionsMenu」を利用しています。

0 件のコメント:

コメントを投稿