android 窗口介绍

dialog是应用类窗口 其子类 大多会改为子窗口
popupwindow是应用类窗口 当其显示时会改为子窗口

contextwindow也是应用类窗口 

optionMenu是应用类窗口

技术分享


应用类视图的根视图都是DecorView

Menu重要类介绍:
Menu: 一个interface 描述了一个菜单应该具备的操作接口 这里的菜单是指整个菜单 而不是一个条目
MenuBuilder是其真正实现
MenuItem: 一个interface 描述一个菜单条目应该具备的操作接口 MenuItemImpl是其实现 该类中保存的条目的数据
ContextMenuBuilder: 该类中有一个Arraylist(MenuItemImpl)变量 用于保存整个菜单的条目信息  
拓展了MenuBuilder 增加了contextMenu的特性
MenuDialogHelper: 提供显示menu的操作

ContextMenu显示流程:
长按->view类的performLongClick()->showContextMenu()->调用mparent.showContextMenuForChild() 此时根视图为(DecorView)
即 DecorView的showContextMenuForChild()->ContextMenuBuilder类的show()->在show()中调用view类的createContextMenu()方法创建详细的条目

->最终调用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;
    }

这里我们直接重写onPreparePanel 为createdPanelView(view)和menu(menu)赋值 达到自定义optionMenu的目标


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。