Instantly share code, notes, and snippets.
Created
March 26, 2013 07:35
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save noxi515/5243718 to your computer and use it in GitHub Desktop.
PopupMenuを生成するクラス
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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