APIレベル10 でも Popup のメニューを作る

android.widget.PopupMenu は、 APIレベル 11 から使用できる。
APIレベル10 でも同様のものが欲しい場合、android.widget.PopupWindow
ListView を表示して似たものを作る。

PopupWindow を継承した ListView を表示するものを用意する。
これには、Handler を渡せるようにしてメニュークリック時のコールバックを渡す。

import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.PopupWindow;
/**
 * PopListMenu
 */

public class PopListMenu extends PopupWindow{
   public PopListMenu(ListView listview, int rowLayoutId, int textId, String items,final Handler...handlers){
      super(listview.getContext());
      listview.setSelected(true);
      listview.requestLayout();
      setContentView(listview);
      setHeight(LayoutParams.WRAP_CONTENT);
      setWidth(LayoutParams.WRAP_CONTENT);
      listview.setAdapter(new ArrayAdapter<String>(listview.getContext(), rowLayoutId, textId, items));
      listview.setOnItemClickListener(new AdapterView.OnItemClickListener(){
         @Override
         public void onItemClick(AdapterView<?> parent, View view, int position, long id){
            for(Handler handler : handlers){
               handler.sendMessage(Message.obtain(handler,position));
            }
            PopListMenu.this.dismiss();

         }
      });
      listview.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
      setWidth(listview.getMeasuredWidth());
      setFocusable(true);
      setTouchable(true);
      setOutsideTouchable(true);
   }
}

2番目の引数、rowLayoutId は、メニュー1項目の表示レイアウト XML のID
3番目の引数、textId は、2番目の引数で定義したレイアウト中の項目名を表示する TextView の ID

例として、メニュー1項目の表示レイアウトを以下のように用意する

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/text1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="18dp"
    android:paddingTop="15dp"
    android:paddingBottom="15dp"
    android:paddingRight="18dp"
 >
</TextView>

・・・pop_text1.xml とする。

アクティビティの onCreate でメニューを表示するトリガになる View と、
メニュー項目名の配列

final ImageButton menuButton = (ImageButton)findViewById(R.id.menuImageButton);
String
 items = { "メニュー1", "メニュー2", "メニュー3", "メニュー4" };


// ListView 色の指定 と、セレクタの指定
ListView listview = new ListView(this);
listview.setBackgroundColor(Color.argb(0xff, 0, 0x60, 0));
listview.setSelector(android.R.drawable.list_selector_background);


// メニューの定義
final PopListMenu menu = new PopListMenu(listview, R.layout.pop_text1, R.id.text1, items
   ,new Handler(){
      @Override
      public void handleMessage(Message msg){
         int selectedPosition = msg.what;
         removeMessages(0);
         // selectedPosition に従ってメニュー項目の処理を実行
      }
   });
);

// メニューを表示するトリガ
menuButton.setOnClickListener(new View.OnClickListener(){
   @Override
   public void onClick(View v){
      if (menu.isShowing()){
         menu.dismiss();
      }else{
         menu.showAsDropDown(menuButton, 0, 0);
         menu.update();
      }
   }
});

以下のようになる。

f:id:posturan:20160313224847j:plain