Skip to content

Instantly share code, notes, and snippets.

@noxi515
Created March 26, 2013 07:35
Show Gist options
  • Save noxi515/5243718 to your computer and use it in GitHub Desktop.
Save noxi515/5243718 to your computer and use it in GitHub Desktop.
PopupMenuを生成するクラス
package jp.co.noxi.weathernow.app;
import jp.co.noxi.weathernow.R;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Build;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListPopupWindow;
import android.widget.PopupMenu;
import android.widget.PopupWindow;
/**
* ポップアップメニューを生成するクラス
*/
public final class PopupMenuBuilder {
/**
* ポップアップメニューのクリックリスナー
*/
public interface OnMenuItemClickListener {
/**
* ポップアップメニューがクリックされた時に呼ばれるコールバック
*
* @param position
* クリックされた位置
*/
public void onMenuItemClick(int position);
}
private Activity mActivity;
private View mAnchorView;
private CharSequence[] mItems;
private ListAdapter mAdapter;
private OnMenuItemClickListener mListener;
public PopupMenuBuilder(Activity activity) {
mActivity = activity;
}
/**
* アンカーのViewを設定する
*
* @param viewId
* アンカーにするViewのId
* @return 自身のインスタンス
*/
public PopupMenuBuilder setAnchorView(int viewId) {
mAnchorView = mActivity.findViewById(viewId);
return this;
}
/**
* アンカーのViewを設定する
*
* @param view
* アンカーにするView
* @return 自身のインスタンス
*/
public PopupMenuBuilder setAnchorView(View view) {
mAnchorView = view;
return this;
}
/**
* 表示アイテム一覧を設定する
*
* @param items
* 表示アイテム一覧
* @return 自身のインスタンス
* @throws IllegalArgumentException
* Items is not CharSequence[], ListAdapter or int/Integer
*/
public PopupMenuBuilder setItems(Object items) {
if (items instanceof CharSequence[]) {
return setItems((CharSequence[]) items);
} else if (items instanceof ListAdapter) {
return setItems((ListAdapter) items);
} else {
try {
return setItems(Integer.valueOf(items.toString()).intValue());
} catch (ClassCastException e) {
throw new IllegalArgumentException(
"Only support CharSequence[], ListAdapter, and int/Integer", e);
}
}
}
/**
* 表示アイテム一覧を設定する
*
* @param itemResId
* 表示アイテム一覧のリソースID
* @return 自身のインスタンス
*/
public PopupMenuBuilder setItems(int itemResId) {
mItems = mActivity.getResources().getTextArray(itemResId);
return this;
}
/**
* 表示アイテム一覧を設定する
*
* @param items
* 表示アイテム一覧
* @return 自身のインスタンス
*/
public PopupMenuBuilder setItems(CharSequence[] items) {
mItems = items;
return this;
}
/**
* 表示するアダプターを設定する
*
* @param adapter
* 表示するアダプター
* @return 自身のインスタンス
*/
public PopupMenuBuilder setItems(ListAdapter adapter) {
mAdapter = adapter;
return this;
}
/**
* クリックリスナーを設定する
*/
public PopupMenuBuilder setOnMenuItemClickListener(OnMenuItemClickListener listener) {
mListener = listener;
return this;
}
/**
* ポップアップメニューを表示する
*/
public void show() {
if (mAnchorView != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
showPopup();
return;
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
showPopupHoneyComb();
return;
}
}
showPopupCompat();
}
/**
* リソースを解放する
*/
private void close() {
mActivity = null;
mAnchorView = null;
mItems = null;
}
/**
* ハニカム以前のこんぱちメニュー
*/
private void showPopupCompat() {
if (mAdapter != null) {
showPopupListCompat();
} else {
final Dialog dialog = new AlertDialog.Builder(mActivity)
.setItems(mItems, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (mListener != null) {
mListener.onMenuItemClick(which);
}
}
})
.create();
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
PopupMenuBuilder.this.close();
}
});
dialog.show();
}
}
/**
* ハニカム以前のこんぱちメニュー
*/
private void showPopupListCompat() {
final Dialog dialog = new AlertDialog.Builder(mActivity)
.setAdapter(mAdapter, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (mListener != null) {
mListener.onMenuItemClick(which);
}
}
})
.create();
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
PopupMenuBuilder.this.close();
}
});
dialog.show();
}
/**
* ICS以降のドロップダウンメニューを表示する
*/
@TargetApi(14)
private void showPopup() {
if (mAdapter != null) {
showPopupListHonewComb();
} else {
final PopupMenu popupMenu = new PopupMenu(mActivity, mAnchorView);
final Menu menu = popupMenu.getMenu();
for (int i = 0; i < mItems.length; i++) {
menu.add(1, i, i, mItems[i]);
}
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
if (mListener != null) {
mListener.onMenuItemClick(item.getItemId());
}
return true;
}
});
popupMenu.setOnDismissListener(new PopupMenu.OnDismissListener() {
@Override
public void onDismiss(PopupMenu menu) {
PopupMenuBuilder.this.close();
}
});
popupMenu.show();
}
}
/**
* ハニカム以降のドロップダウンメニューを表示する
*/
@TargetApi(11)
private void showPopupHoneyComb() {
if (mAdapter != null) {
showPopupListHonewComb();
} else {
final PopupMenu popupMenu = new PopupMenu(mActivity, mAnchorView);
final Menu menu = popupMenu.getMenu();
for (int i = 0; i < mItems.length; i++) {
menu.add(1, i, i, mItems[i]);
}
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
if (mListener != null) {
mListener.onMenuItemClick(item.getItemId());
}
PopupMenuBuilder.this.close();
return true;
}
});
popupMenu.show();
}
}
/**
* ハニカム以降のドロップダウンメニューを表示する
*/
@TargetApi(11)
private void showPopupListHonewComb() {
final ListPopupWindow window = new ListPopupWindow(mActivity);
window.setAnchorView(mAnchorView);
window.setAdapter(mAdapter);
window.setWidth(mActivity.getResources().getDimensionPixelSize(R.dimen.popupmenu_width));
window.setModal(true);
window.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
if (mListener != null) {
mListener.onMenuItemClick((int) id);
}
window.dismiss();
}
});
window.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
PopupMenuBuilder.this.close();
}
});
window.show();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment