使用PopupWindow定制菜单界面:

public class MainActivity extends Activity
{
    /**
     * menu的要求:
     * 1.显示:点击menu键
     * 2.退出:
     * (1)再次点击menu
     * (2)点击menu选项
     * (3)点击menu(通知除外)以外的地方
     * (4)点击back键
     * (5)进入暂停状态
     *
     */
                                                          
    private PopupWindow mPopupMenu;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
                                                              
        LayoutInflater inflater = getLayoutInflater();
        View menulayout = inflater.inflate(R.layout.optionmenu_layout, null);
                                                              
        mPopupMenu = new PopupWindow(menulayout, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
                                                              
        //监听菜单按钮
        menulayout.findViewById(R.id.textView1).setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                mPopupMenu.dismiss();
            }
        });
                                                              
        //点击菜单的layout就隐藏
        menulayout.findViewById(R.id.mainmenu).setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                mPopupMenu.dismiss();
            }
        });
                                                              
    }
                                                          
      //监听返回键
//    @Override
//    public void onBackPressed()
//    {
//        if(mPopupMenu.isShowing())
//        {
//            mPopupMenu.dismiss();
//        }
//        else
//        {
//            super.onBackPressed();
//        }
//    }
                                                         
    //暂停状态
    @Override
    protected void onPause()
    {
        if(mPopupMenu.isShowing())
        {
            mPopupMenu.dismiss();
        }
        super.onPause();
    }
                                                          
                                                          
    //监听menu键和返回键
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        if(keyCode == KeyEvent.KEYCODE_MENU)
        {
            if(mPopupMenu.isShowing())
            {
                mPopupMenu.dismiss();
            }
            else
            {
                mPopupMenu.showAtLocation(findViewById(R.id.main), Gravity.BOTTOM, 0, 0);
            }
            return true;
        }
        if(keyCode == KeyEvent.KEYCODE_BACK)
        {
            if(mPopupMenu.isShowing())
            {
                mPopupMenu.dismiss();
            }
          else
          {
              finish();
          }
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
                                                          
                                                          
                                                          
                                                          
                                                          
    //4.2版本会默认自行启动此方法
    /**
    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        if(mPopupMenu.isShowing())
        {
            mPopupMenu.dismiss();
        }
        else
        {
            mPopupMenu.showAtLocation(findViewById(R.id.main), Gravity.BOTTOM, 0, 0);
        }
        //设置成false,则每次按menu都会启动onCreateOptionsMenu方法,否则只在创建时启动一次
        return false;
    }
    */
                                                          
}



PopupWindow相关总结:

1.点击PopupWindow外区域关闭PopupWindow,监听PopupWindow

//设置电话菜单背景,点击菜单外区域隐藏菜单
mPhoneMenu.setBackgroundDrawable(getResources().getDrawable(R.color.emptylayout_bg));//必须设置背景setOutsideTouchable才有效
mPhoneMenu.setFocusable(true);// menu菜单获得焦点,menu里的控件才能有点击事件
mPhoneMenu.setOutsideTouchable(false);//设置点击menu外的区域后隐藏menu
mPhoneMenu.update();//必须使用update方法
//监听菜单关闭时,打开底部菜单
mPhoneMenu.setOnDismissListener(new OnDismissListener()
{
    @Override
    public void onDismiss()
    {
        showBottomMenu();
    }
});


2.WindowManager$BadTokenException错误解决方法

http://glblong.blog.51cto.com/3058613/1306012


3.指定菜单在某个View的相对位置

                    
                    popupWindow = new PopupWindow(layout,120,120);  //需要设置固定宽高,popupWindow.getHeight()才有效
                    popupWindow.setFocusable(true);  
                    popupWindow.setOutsideTouchable(true);  
                    popupWindow.setBackgroundDrawable(new BitmapDrawable());  

                    int[] location = new int[2];//获取基准位置view的坐标位置  
                    view.getLocationOnScreen(location);

                    popupWindow.showAtLocation(view, Gravity.NO_GRAVITY, location[0], location[1]-popupWindow.getHeight());