【AndroidのViewを制する】 PopupMenuを使いこなしてViewに紐付いたメニューを表示する
今回、紹介する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());