要自定义Menu,需要先了解Menu的特点:
显示的情形包括:
1,
按menu键,显示
关闭的情形包括:
1,
back键
2,
再次按menu键
3,
按menu区域之外的地方
4,
执行onPause()和onStop()方法
5,
点击Menuitem
依照以上特点来模拟:
Step1:创建我们自定义的菜单,通过popWindow创建。代码如下:
准备:自定义menu的xml布局文件,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);
}
}
// 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;
}
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(),虽然新的API有onBackPressed()事件,但是为了兼容起见,仍然使用本方法。
查看方法的注释: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);
}
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();
}
}
// 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);
动画可依照个人的喜好完成。
转载于:https://blog.51cto.com/mikewang/740311