package com.u1aryz.android.lib.newpopupmenu; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.content.Context; import android.graphics.Rect; import android.util.DisplayMetrics; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.WindowManager; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.PopupWindow; import android.widget.TextView; public class PopupMenu { private Context mContext; private LayoutInflater mInflater; private WindowManager mWindowManager; private PopupWindow mPopupWindow; private View mContentView; private ListView mItemsView; private TextView mHeaderTitleView; private OnItemSelectedListener mListener; private List<MenuItem> mItems; private int mWidth = 240; private float mScale; public PopupMenu(Context context) { mContext = context; mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics metrics = new DisplayMetrics(); mWindowManager.getDefaultDisplay().getMetrics(metrics); mScale = metrics.scaledDensity; mItems = new ArrayList<MenuItem>(); mPopupWindow = new PopupWindow(context); mPopupWindow.setTouchInterceptor(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_OUTSIDE) { mPopupWindow.dismiss(); return true; } return false; } }); setContentView(mInflater.inflate(R.layout.popup_menu, null)); } /** * Sets the popup's content. * * @param contentView */ private void setContentView(View contentView) { mContentView = contentView; mItemsView = (ListView) contentView.findViewById(R.id.items); mHeaderTitleView = (TextView) contentView.findViewById(R.id.header_title); mPopupWindow.setContentView(contentView); } /** * Add menu item. * * @param itemId * @param titleRes * @param iconRes * * @return item */ public MenuItem add(int itemId, int titleRes) { MenuItem item = new MenuItem(); item.setItemId(itemId); item.setTitle(mContext.getString(titleRes)); mItems.add(item); return item; } /** * Show popup menu. */ public void show() { show(null); } /** * Show popup menu. * * @param anchor */ public void show(View anchor) { if (mItems.size() == 0) { throw new IllegalStateException("PopupMenu#add was not called with a menu item to display."); } preShow(); MenuItemAdapter adapter = new MenuItemAdapter(mContext, mItems); mItemsView.setAdapter(adapter); mItemsView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if (mListener != null) { mListener.onItemSelected(mItems.get(position)); } mPopupWindow.dismiss(); } }); if (anchor == null) { View parent = ((Activity)mContext).getWindow().getDecorView(); mPopupWindow.showAtLocation(parent, Gravity.CENTER, 0, 0); return; } int xPos, yPos; int[] location = new int[2]; anchor.getLocationOnScreen(location); Rect anchorRect = new Rect(location[0], location[1], location[0] + anchor.getWidth(), location[0] + anchor.getHeight()); mContentView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); mContentView.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); int rootHeight = mContentView.getMeasuredHeight(); int screenHeight = mWindowManager.getDefaultDisplay().getHeight(); // Set x-coordinate to display the popup menu xPos = anchorRect.centerX() - mPopupWindow.getWidth() / 2; int dyTop = anchorRect.top; int dyBottom = screenHeight + rootHeight; boolean onTop = dyTop > dyBottom; // Set y-coordinate to display the popup menu if (onTop) { yPos = anchorRect.top - rootHeight; } else { if (anchorRect.bottom > dyTop) { yPos = anchorRect.bottom - 20; } else { yPos = anchorRect.top - anchorRect.bottom + 50; } } mPopupWindow.showAtLocation(anchor, Gravity.NO_GRAVITY, xPos, yPos); } private void preShow() { int width = (int) (mWidth * mScale); mPopupWindow.setWidth(width); mPopupWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT); mPopupWindow.setTouchable(true); mPopupWindow.setFocusable(true); mPopupWindow.setOutsideTouchable(true); mPopupWindow.setAnimationStyle(android.R.style.Animation_Dialog); mPopupWindow.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.panel_background)); } /** * Dismiss the popup menu. */ public void dismiss() { if (mPopupWindow != null && mPopupWindow.isShowing()) { mPopupWindow.dismiss(); } } /** * Sets the popup menu header's title. * * @param title */ public void setHeaderTitle(CharSequence title) { mHeaderTitleView.setText(title); mHeaderTitleView.setVisibility(View.VISIBLE); mHeaderTitleView.requestFocus(); } /** * Change the popup's width. * * @param width */ public void setWidth(int width) { mWidth = width; } /** * Register a callback to be invoked when an item in this PopupMenu has * been selected. * * @param listener */ public void setOnItemSelectedListener(OnItemSelectedListener listener) { mListener = listener; } /** * Interface definition for a callback to be invoked when * an item in this PopupMenu has been selected. */ public interface OnItemSelectedListener { public void onItemSelected(MenuItem item); } static class ViewHolder { ImageView icon; TextView title; } private class MenuItemAdapter extends ArrayAdapter<MenuItem> { public MenuItemAdapter(Context context, List<MenuItem> objects) { super(context, 0, objects); } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = mInflater.inflate(R.layout.menu_list_item, null); holder = new ViewHolder(); holder.icon = (ImageView) convertView.findViewById(R.id.icon); holder.title = (TextView) convertView.findViewById(R.id.title); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } MenuItem item = getItem(position); if (item.getIcon() != null) { holder.icon.setImageDrawable(item.getIcon()); holder.icon.setVisibility(View.VISIBLE); } else { holder.icon.setVisibility(View.GONE); } holder.title.setText(item.getTitle()); return convertView; } } }