要自定义Menu,需要先了解Menu的特点:

 

显示的情形包括:

1,      menu键,显示

关闭的情形包括:

1,  back

2,  再次按menu

3,  menu区域之外的地方

4,  执行onPause()onStop()方法

5,  点击Menuitem

 

 

依照以上特点来模拟:

 

Step1:创建我们自定义的菜单,通过popWindow创建。代码如下:

       准备:自定义menuxml布局文件,menuitem的监听。

 

private void initMenu() {
     // TODO Auto-generated method stub
    LayoutInflater inflater = LayoutInflater.from( this);
    mMenuContentView = (RelativeLayout) inflater.inflate(R.layout.menu,
         null);
    mPopupWindow = new PopupWindow(mMenuContentView,
        LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
    mPopupWindow.setAnimationStyle(R.style.my_menu);
     for ( int i = 0; i < mMenuItemIDs.length; i++) {
      mMenuContentView.findViewById(mMenuItemIDs[i]).setOnClickListener(
           this);
    }

  }

 

Step2:按menu键,显示

覆写菜单创建方法onCreateOptionsMenu()

 

方法的注释为:*@return You must return true for the menu to be displayed;if you return false it will not be shown.

W:返回值为真,则显示默认的menu,返回值为false,则不显示menu

 

因为我们要实现自定义的菜单,所以,将返回值改为false

 

代码如下:

 

@Override

                 public boolean onCreateOptionsMenu(

                                                        Menu menu) {

                                     if (mOptionsMenu.isShowing()) {

                                                        mOptionsMenu.dismiss();

                                     } else {

                                                        View findViewById = findViewById(R.id.main);

                                                        mOptionsMenu.showAtLocation(

                                                                                             findViewById,

                                                                                             Gravity.BOTTOM, 0, 0);

                                     }

                                     return false;

                 }
 

 

Step3:按back键,menu消失

 

覆写按键触发事件,使用onKeyDown(),虽然新的APIonBackPressed()事件,但是为了兼容起见,仍然使用本方法。

 

查看方法的注释:Returns: Return true to prevent this event from being propagated further, or false to indicate that you have not handled this event and it should continue to be propagated.

 

W:返回值为真,阻止此按键的默认响应下一步事件。显然,我们只需要按了back键之后,执行我们想要的操作,设置返回值为真。

 

@Override

                 public boolean onKeyDown( int keyCode, KeyEvent event) {

                                     // TODO Auto-generated method stub

                                     if (KeyEvent.KEYCODE_BACK == keyCode) {

                                                         if (mPopupWindow.isShowing()) {

                                                                         mPopupWindow.dismiss();

                                                                         return true;

                                                        }

                                     }

    

                                     return super.onKeyDown(keyCode, event);

                 }

    
 

 

Step4:按menu以外的区域,meu消失,却不会触发以外区域的应用

 

只要用一个view布局覆盖自定义menu以外的区域即可,透明,点击后,整体消失即可。

 

Step5:执行onPause()onStop()方法

覆写onPause()方法,判断popupWindow的状态,如果是显示的,则消失

 

代码如下:
 

 

protected void onPause() {

                                     // TODO Auto-generated method stub

                                     super.onPause();

                                     if (mPopupWindow.isShowing()) {

                                                        mPopupWindow.dismiss();

                                     }

                 }
 

 

 

Step6:点击菜单选项后,菜单消失

显然,menuitem监听事件响应后,mPopupWindow.dismiss()即可。

 

Advanced

 

Step7:设置menu显示的动画,当然是设置popupWindow的属性

 

代码如下:mPopupWindow.setAnimationStyle(R.style.my_menu);

动画可依照个人的喜好完成。