optionMenu如何弹出

1.我们通过工具抓取的是 
ListMenuPresenter.java 
2.通过分析得到
ListMenuPresenter.java  (里面包含BaseAdapter)-->  ExpandedMenuView.java extends ListView  --> ListMenuItemView.java
ListMenuItemView.java extends LinearLayout implements MenuView.ItemView
3.

通过这个我们知道ListMenuPresenter.java文件只是在MenuDialogHelper.java 文件和PhoneWindows.java文件里面使用。
先看MenuDialogHelper.java文件
MenuDialogHelper.java :Helper for menus that appear as Dialogs (context and submenus).
就是将optionmenu中的item通过AlertDialog 的方式呈现
@Override
public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
if (!subMenu.hasVisibleItems()) return false;

// The window manager will give us a token.
new MenuDialogHelper(subMenu).show(null);
if (mCallback != null) {
mCallback.onOpenSubMenu(subMenu);
}
return true;
}
在调用subMenu的时候,是通过dialog的方式。
然后分析PhoneWhindow.java 
MenuView getListMenuView(Context context, MenuPresenter.Callback cb) {
if (menu == null) return null;

if (!isCompact) {
getIconMenuView(context, cb); // Need this initialized to know where our offset goes
}

if (listMenuPresenter == null) {
listMenuPresenter = new ListMenuPresenter(
R.layout.list_menu_item_layout, listPresenterTheme);
listMenuPresenter.setCallback(cb);
listMenuPresenter.setId(R.id.list_menu_presenter);
menu.addMenuPresenter(listMenuPresenter);
}

if (iconMenuPresenter != null) {
listMenuPresenter.setItemIndexOffset(
iconMenuPresenter.getNumActualItemsShown());
}
MenuView result = listMenuPresenter.getMenuView(decorView);

return result;
}

这边可以看出来R.layout.list_menu_item_layout 问价加载并且设置了 listPresenterTheme 的属性。
最后的listMenuPresenter.getMenuView(decorView);就是将这个View 加入到decorView 这个root节点中。

4.所以看到这边也就大体清晰了,然后我们看一下这个result的作用。
通过查看result我们得到:
protected boolean initializePanelContent(PanelFeatureState st) {
......

if (mPanelMenuPresenterCallback == null) {
mPanelMenuPresenterCallback =
new PanelMenuPresenterCallback();
}

MenuView menuView = st.isInListMode()
? st.getListMenuView(getContext()
, mPanelMenuPresenterCallback)
: st.getIconMenuView(getContext()
, mPanelMenuPresenterCallback);

st.shownPanelView = (View) menuView;

if (st.shownPanelView != null) {
// Use the menu View's default animations if it has any
final int defaultAnimations = menuView.getWindowAnimations();
if (defaultAnimations != 0) {
st.windowAnimations = defaultAnimations
;
}
return true;
} else {
return false;
}
}
PanelFeatureState.class 这个内部类中有很多的属性。其中有关于DocorView ,还有menu View -> showPanelView 是否跟新PhoneWindow这样的属性。貌似就可WindowsManger.LayoutParams 类似。
将这个 menuView。WindowsAnimations给了 PanelFeatureState这个 windowAnimations .
5.之后我们找到
private void openPanel(final PanelFeatureState st, KeyEvent event) {    // System.out.println("Open panel: isOpen=" + st.isOpen);
......

ViewParent shownPanelParent = st.shownPanelView.getParent();
if (shownPanelParent != null && shownPanelParent instanceof ViewGroup) {
((ViewGroup) shownPanelParent).removeView(st.shownPanelView)
;
}
st.decorView.addView(st.shownPanelView
, lp);

......
st.isHandled =
false;

WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
width
, WRAP_CONTENT,
st.x, st.y, WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG,
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
,
st.decorView.mDefaultOpacity);

if (st.isCompact) {
lp.gravity = getOptionsPanelGravity()
;
sRotationWatcher.addWindow(this);
} else {
lp.gravity = st.gravity
;
}

lp.windowAnimations = st.windowAnimations
;

// Add begin by meitu.liujr for option menu theme
lp.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
lp.dimAmount = 0.6f;
// Add end
wm.addView(st.decorView, lp);
st.isOpen = true;
// Log.v(TAG, "Adding main menu to window manager.");
}
shownPanelView的父布局去掉,然后加入到docorView 中,然后将docorView 加入到PhoneWindow中。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值