【AndroidのViewを制する】 PopupMenuを使いこなしてViewに紐付いたメニューを表示する

このエントリーを Google ブックマーク に追加
Pocket
[`yahoo` not found]

今回、紹介するPopupMenuは設定したViewの近くにMenuをポップアップすることができます。

PopupMenuのコンストラクタ

PopupMenuには3つのコンストラクタが存在しています。
PopupMenu(Context context, View anchor) 一番簡単なコンストラクダです。「コンテキスト」と「PopupMenuを表示するView」を引数として渡します。
PopupMenu(Context context, View anchor, int gravity) 「コンテキスト」と「PopupMenuを表示するView」、「PopupMenuが表示される位置のGravity」を引数として渡します。
PopupMenu(Context context, View anchor, int gravity, int popupStyleAttr, int popupStyleRes) 「コンテキスト」と「PopupMenuを表示するView」、「PopupMenuが表示される位置のGravity」、 「PopupMenuに適用されるスタイルリソース」、「popupStyleAttrが見つからない時に適用するスタイルリソース」を引数として渡します。


    FrameLayout frameLayout = new FrameLayout(this);
    FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT , 500);
    layoutParams.gravity = Gravity.CENTER;
    // PopupMenuが表示されるViewを作成する
    final TextView addedPopupMenuView = new TextView(this);
    addedPopupMenuView.setGravity(Gravity.CENTER);
    addedPopupMenuView.setBackgroundColor(Color.LTGRAY);
    addedPopupMenuView.setLayoutParams(layoutParams);
    addedPopupMenuView.setText("PopupMenuを表示する");
    frameLayout.addView(addedPopupMenuView);
    setContentView(frameLayout);

    // PopupMenuのインスタンスを作成する
    popupMenu = new PopupMenu(PopupMenuActivity.this, addedPopupMenuView);


PopupMenu#inflateを使ってMenuをインフレートする

PopupMenu#inflateはMenuリソースを使ってMenuの内容を作成するメソッドです。
PopupMenu#getMenuはインフレートされたMenuを取得するメソッドです。

    FrameLayout frameLayout = new FrameLayout(this);
    FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT , 500);
    layoutParams.gravity = Gravity.CENTER;
    // PopupMenuが表示されるViewを作成する
    final TextView addedPopupMenuView = new TextView(this);
    addedPopupMenuView.setGravity(Gravity.CENTER);
    addedPopupMenuView.setBackgroundColor(Color.LTGRAY);
    addedPopupMenuView.setLayoutParams(layoutParams);
    addedPopupMenuView.setText("PopupMenuを表示する");
    frameLayout.addView(addedPopupMenuView);
    setContentView(frameLayout);

    // PopupMenuのインスタンスを作成する
    popupMenu = new PopupMenu(PopupMenuActivity.this, addedPopupMenuView);

    // Menumをインフレートする
    popupMenu.inflate(R.menu.popupmenu);


今回使用するMenuリソースは下記のようになっています。

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
        <item
            android:title="ADD"/>
        <item
            android:title="EDIT" />
    </menu>


PopupMenu#show/PopupMenu#dismissを使ってMenuを表示/非表示する

PopupMenu#showはPopupMenuを表示するメソッドです。
PopupMenu#dismissはPopupMenuを非表示するメソッドです。
このメソッドはActivityの起動が完了していないActivity#onCreateで呼ぶと例外で強制終了します。
PopupMenuで表示されたMenuは「Menu外をタッチした時」や「アイテムを選択した時」に非表示になります。


    FrameLayout frameLayout = new FrameLayout(this);
    FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT , 500);
    layoutParams.gravity = Gravity.CENTER;
    // PopupMenuが表示されるViewを作成する
    final TextView addedPopupMenuView = new TextView(this);
    addedPopupMenuView.setGravity(Gravity.CENTER);
    addedPopupMenuView.setBackgroundColor(Color.LTGRAY);
    addedPopupMenuView.setLayoutParams(layoutParams);
    addedPopupMenuView.setText("PopupMenuを表示する");
    frameLayout.addView(addedPopupMenuView);
    setContentView(frameLayout);

    // PopupMenuのインスタンスを作成する
    popupMenu = new PopupMenu(PopupMenuActivity.this, addedPopupMenuView);

    // Menumをインフレートする
    popupMenu.inflate(R.menu.popupmenu);

    LinearLayout linearLayout = new LinearLayout(this);
    // PopupMenuを表示するボタンを作成
    Button showPopupMenu = new Button(this);
    showPopupMenu.setText("PopupMenuを表示する");
    showPopupMenu.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // PopupMenu#showでMenuを表示する
            popupMenu.show();
        }
    });

    // PopupMenuを消すボタンを作成
    Button hidePopupMenu = new Button(this);
    hidePopupMenu.setText("PopupMenuを消す");
    hidePopupMenu.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // PopupMenu#hideでMenuを消す
            popupMenu.dismiss();
        }
    });

    linearLayout.addView(showPopupMenu);
    linearLayout.addView(hidePopupMenu);
    frameLayout.addView(linearLayout);


PopupMenu#setGravityを使ってMenuの表示位置を変更する

PopupMenu#setGravityはPopupMenuを表示位置を変更するメソッドです。
PopupMenu#getGravityはPopupMenuに設定されている表示位置を返却するメソッドです。


    FrameLayout frameLayout = new FrameLayout(this);
    FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT , 500);
    layoutParams.gravity = Gravity.CENTER;
    // PopupMenuが表示されるViewを作成する
    final TextView addedPopupMenuView = new TextView(this);
    addedPopupMenuView.setGravity(Gravity.CENTER);
    addedPopupMenuView.setBackgroundColor(Color.LTGRAY);
    addedPopupMenuView.setLayoutParams(layoutParams);
    addedPopupMenuView.setText("PopupMenuを表示する");
    frameLayout.addView(addedPopupMenuView);
    setContentView(frameLayout);

    // PopupMenuのインスタンスを作成する
    popupMenu = new PopupMenu(PopupMenuActivity.this, addedPopupMenuView);

    // Menumをインフレートする
    popupMenu.inflate(R.menu.popupmenu);

    // Menuの表示位置を変更する
    popupMenu.setGravity(Gravity.RIGHT);


PopupMenu#setOnMenuItemClickListenerを使ってアイテム選択をコールバックを設定する

PopupMenu#setOnMenuItemClickListenerはPopupMenu内のアイテムの選択を検知するコールバックインターフェースを設定するメソッドです。
OnMenuItemClickListenerのインターフェースが引数になります、 OnMenuItemClickListener#onMenuItemClickはアイテムが選択された時に呼ばれるメソッドです。 引数のMenuItemは選択されたアイテムの情報を持つインスタンスです。

    FrameLayout frameLayout = new FrameLayout(this);
    FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT , 500);
    layoutParams.gravity = Gravity.CENTER;
    // PopupMenuが表示されるViewを作成する
    final TextView addedPopupMenuView = new TextView(this);
    addedPopupMenuView.setGravity(Gravity.CENTER);
    addedPopupMenuView.setBackgroundColor(Color.LTGRAY);
    addedPopupMenuView.setLayoutParams(layoutParams);
    addedPopupMenuView.setText("PopupMenuを表示する");
    frameLayout.addView(addedPopupMenuView);
    setContentView(frameLayout);

    // PopupMenuのインスタンスを作成する
    popupMenu = new PopupMenu(PopupMenuActivity.this, addedPopupMenuView);

    // Menumをインフレートする
    popupMenu.inflate(R.menu.popupmenu);

    // OnMenuItemClickListenerを設定しアイテムの選択をコールバックする
    popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
        @Override
        public boolean onMenuItemClick(MenuItem item) {
            // 引数は選択されたMenuItemインスタンスです。
            Toast.makeText(PopupMenuActivity.this, item.getTitle() + "が押されました", Toast.LENGTH_SHORT).show();
            return false;
        }
    });


PopupMenu#setOnDismissListenerを使ってMenuの非表示をコールバックを設定する

PopupMenu#setOnDismissListenerはMenuが消えたことを検知するコールバックインターフェースを設定するメソッドです。
OnDismissListenerのインターフェースが引数になります、OnDismissListenerr#onDismissはPopupMenuが消えた時に呼ばれるメソッドです。
引数のPopupMenuは非表示になったPopupMenuの情報を持つインスタンスです。


    FrameLayout frameLayout = new FrameLayout(this);
    FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT , 500);
    layoutParams.gravity = Gravity.CENTER;
    // PopupMenuが表示されるViewを作成する
    final TextView addedPopupMenuView = new TextView(this);
    addedPopupMenuView.setGravity(Gravity.CENTER);
    addedPopupMenuView.setBackgroundColor(Color.LTGRAY);
    addedPopupMenuView.setLayoutParams(layoutParams);
    addedPopupMenuView.setText("PopupMenuを表示する");
    frameLayout.addView(addedPopupMenuView);
    setContentView(frameLayout);

    // PopupMenuのインスタンスを作成する
    popupMenu = new PopupMenu(PopupMenuActivity.this, addedPopupMenuView);

    // Menumをインフレートする
    popupMenu.inflate(R.menu.popupmenu);

    // OnDismissListenerを設定しPopupMenuが消えたことをコールバックされる
    popupMenu.setOnDismissListener(new PopupMenu.OnDismissListener() {
        @Override
        public void onDismiss(PopupMenu menu) {
            // 引数は非表示になったPopupMenuインスタンスです。
            Toast.makeText(PopupMenuActivity.this, "PopupMenuが消えました", Toast.LENGTH_SHORT).show();
        }
    });


PopupMenu#getDragToOpenListenerを使ってドラッグオープンを有効にする

PopupMenu#getDragToOpenListenerはドラッグオープンが実装されたView.OnTouchListenerを返却するメソッドです。
取得したView.OnTouchListenerをViewに設定することで、Viewをドラッグしたまま指がViewの外に出ることでPopupMenuを表示することができます。
また、この方法で表示されたPopupMenuは「メニューアイテム上でドラッグをやめる」か「PopupMenu外でドラッグをやめる」の どちらかしかできないことに注意しましょう。


    FrameLayout frameLayout = new FrameLayout(this);
    FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT , 500);
    layoutParams.gravity = Gravity.CENTER;
    // PopupMenuが表示されるViewを作成する
    final TextView addedPopupMenuView = new TextView(this);
    addedPopupMenuView.setGravity(Gravity.CENTER);
    addedPopupMenuView.setBackgroundColor(Color.LTGRAY);
    addedPopupMenuView.setLayoutParams(layoutParams);
    addedPopupMenuView.setText("PopupMenuを表示する");
    frameLayout.addView(addedPopupMenuView);
    setContentView(frameLayout);

    // PopupMenuのインスタンスを作成する
    popupMenu = new PopupMenu(PopupMenuActivity.this, addedPopupMenuView);

    // Menumをインフレートする
    popupMenu.inflate(R.menu.popupmenu);

    // PopupMenuドラッグオープンを有効にする
    addedPopupMenuView.setOnTouchListener(popupMenu.getDragToOpenListener());