contextwindow也是应用类窗口
optionMenu是应用类窗口
应用类视图的根视图都是DecorView
->最终调用MenuDialogHelper类的show()方法 完成显示
创建optionMenu的3种方法:
当按下menu键时会调用phoneWindow的preparePanel方法
public final boolean preparePanel(PanelFeatureState st, KeyEvent event) {
// Already prepared (isPrepared will be reset to false later)
if (st.isPrepared)
return true;
if ((mPreparedPanel != null) && (mPreparedPanel != st)) {
// Another Panel is prepared and possibly open, so close it
closePanel(mPreparedPanel, false);
}
final Callback cb = getCallback();
//cb==activity
if (cb != null) {
//调用onCreatePanelView来显示一个自定义的optionMenu
st.createdPanelView = cb.onCreatePanelView(st.featureId);
}
if (st.createdPanelView == null) {
// Init the panel state's menu--return false if init failed
if (st.menu == null) {
if (!initializePanelMenu(st) || (st.menu == null)) {
return false;
}
// Call callback, and return if it doesn't want to display menu
//调用activity的oncreateOptionMenu来创建一个Menu
if ((cb == null) || !cb.onCreatePanelMenu(st.featureId, st.menu)) {
// Ditch the menu created above
st.menu = null;
return false;
}
}
// Callback and return if the callback does not want to show the menu
//onPreparePanel自定义optionMenu
if (!cb.onPreparePanel(st.featureId, st.createdPanelView, st.menu)) {
return false;
}
// Set the proper keymap
KeyCharacterMap kmap = KeyCharacterMap.load(event != null ? event.getDeviceId() : 0);
st.qwertyMode = kmap.getKeyboardType() != KeyCharacterMap.NUMERIC;
st.menu.setQwertyMode(st.qwertyMode);
}
// Set other state
st.isPrepared = true;
st.isHandled = false;
mPreparedPanel = st;
return true;
}先看几个概念
分析上述代码 :可以看到有3处注释
在这3处注释中分别用了3种方式来创建一个menu
这里的CallBack就是Activity (activity实现了callback接口)
1.onCreatePanelView
acitivity的onCreatePanelView方法
public View onCreatePanelView(int featureId) {
return null;
}
st.createdPanelView = cb.onCreatePanelView(st.featureId);
通过重写onCreatePanelView 我们可以更改createdPanelView 的值 从而实现自定义optionMenu
2.cb.onCreatePanelMenu(st.featureId, st.menu)
public boolean onCreatePanelMenu(int featureId, Menu menu) {
if (featureId == Window.FEATURE_OPTIONS_PANEL) {
return onCreateOptionsMenu(menu);
}
return false;
}
这里调用onCreateOptionMenu方法 也是我们创建OptionMenu最常用的方法
这里提供了一个menu对象 让我们来进行操作 而对于背景view则是使用默认的
再看:
if ((cb == null) || !cb.onCreatePanelMenu(st.featureId, st.menu)) {
// Ditch the menu created above
st.menu = null;
return false;
}onCreatePanelMenu默认返回值是false 在if语句中也就是true
所以执行st.menu = null;
所以我们重写onCreatePanelMenu一定要返回ture
3.onPreparePanel
public boolean onPreparePanel(int featureId, View view, Menu menu) {
if (featureId == Window.FEATURE_OPTIONS_PANEL && menu != null) {
boolean goforit = onPrepareOptionsMenu(menu);
return goforit && menu.hasVisibleItems();
}
return true;
}
原文:http://blog.csdn.net/d342784178/article/details/45915753