每个矩形框表示一个View,上面展示了View的类型、索引号和id,三个颜色球表示的分别是该view的测量、布局和绘画的时间性能,红的最慢,绿的最快,如果你把鼠标放到矩形框上可以看到具体时间,右下角的数字表示该view在父视图的位置,以0开始,这张截图是hierarchyView给出截图的一部分,由于我们只关注AB的布局,content和其它内容先不看。
mHandler.postDelayed(new Runnable() { @Override public void run() { // TODO Auto-generated method stub handle_focus(); } }, 300); private void handle_focus(){ Log.i(TAG, "handle_focus begin!"); int actionMenuViewIndex=-1; int actionBarViewIndex=-1; int actionBarContainerIndex=-1; ViewGroup rView = (ViewGroup) getWindow().getDecorView(); ViewGroup ll = (ViewGroup)rView.getChildAt(0); for( int i=0;i<ll.getChildCount();i++){ if(ll.getChildAt(i) instanceof ActionBarContainer){ actionBarContainerIndex = i; break; } } ActionBarContainer action_bar = (ActionBarContainer)ll.getChildAt(actionBarContainerIndex); if(action_bar!=null){ for( int i=0;i<action_bar.getChildCount();i++){ if(action_bar.getChildAt(i) instanceof ActionBarView){ actionBarViewIndex =i; break; } } ActionBarView ABview =(ActionBarView) action_bar.getChildAt(actionBarViewIndex); if(ABview!=null){ if (DEBUG) Log.d(TAG, "Aview != null + count = " + ABview.getChildCount()); for( int i=0;i<ABview.getChildCount();i++){ if (DEBUG) Log.d(TAG, "i = " + i + " " + ABview.getChildAt(i)); if(ABview.getChildAt(i) instanceof ActionMenuView){ if (DEBUG) Log.d(TAG, i + "th Aview's child is instanceof ActionMenuView"); actionMenuViewIndex =i; break; } } } if (DEBUG) Log.d(TAG, "indexOf_ActionBarContainer = " + actionBarContainerIndex + "indexOf_ActionBarView = " + actionBarViewIndex + "indexOf_ActionmenuView = " + actionMenuViewIndex); if(actionMenuViewIndex!=-1){ ActionMenuView AmView =(ActionMenuView)ABview.getChildAt(actionMenuViewIndex); view_menu_cancel=(ActionMenuItemView)AmView.getChildAt(0); view_menu_down = (ActionMenuItemView)AmView.getChildAt(1); if (view_menu_down != null) { Log.i(TAG, "view_pictrue request focus!"); view_menu_down.requestFocus(); } if (view_menu_cancel != null) { view_menu_cancel.setNextFocusUpId(view_menu_down.getId()); } } } }
<com.android.internal.widget.ActionBarOverlayLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/action_bar_overlay_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:splitMotionEvents="false"> <FrameLayout android:id="@android:id/content" android:layout_width="match_parent" android:layout_height="match_parent" /> <LinearLayout android:id="@+id/top_action_bar" android:layout_width="match_parent" android:layout_height="wrap_content"> <com.android.internal.widget.ActionBarContainer android:id="@+id/action_bar_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" style="?android:attr/actionBarStyle" android:gravity="top"> <com.android.internal.widget.ActionBarView android:id="@+id/action_bar" android:layout_width="match_parent" android:layout_height="wrap_content" style="?android:attr/actionBarStyle" /> <com.android.internal.widget.ActionBarContextView android:id="@+id/action_context_bar" android:layout_width="match_parent" android:layout_height="wrap_content" android:visibility="gone" style="?android:attr/actionModeStyle" /> </com.android.internal.widget.ActionBarContainer> <ImageView android:src="?android:attr/windowContentOverlay" android:scaleType="fitXY" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> <com.android.internal.widget.ActionBarContainer android:id="@+id/split_action_bar" android:layout_width="match_parent" android:layout_height="wrap_content" style="?android:attr/actionBarSplitStyle" android:visibility="gone" android:gravity="center"/> </com.android.internal.widget.ActionBarOverlayLayout>以上代码取自Master分支,不同版本略有不同。
public void setMenu(Menu menu, MenuPresenter.Callback cb) { if (menu == mOptionsMenu) return; if (mOptionsMenu != null) { mOptionsMenu.removeMenuPresenter(mActionMenuPresenter); mOptionsMenu.removeMenuPresenter(mExpandedMenuPresenter); } MenuBuilder builder = (MenuBuilder) menu; mOptionsMenu = builder; if (mMenuView != null) { final ViewGroup oldParent = (ViewGroup) mMenuView.getParent(); if (oldParent != null) { oldParent.removeView(mMenuView); } } if (mActionMenuPresenter == null) { mActionMenuPresenter = new ActionMenuPresenter(mContext); mActionMenuPresenter.setCallback(cb); mActionMenuPresenter.setId(com.android.internal.R.id.action_menu_presenter); mExpandedMenuPresenter = new ExpandedActionViewMenuPresenter(); } ActionMenuView menuView; final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); if (!mSplitActionBar) { mActionMenuPresenter.setExpandedActionViewsExclusive( getResources().getBoolean( com.android.internal.R.bool.action_bar_expanded_action_views_exclusive)); configPresenters(builder); menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); final ViewGroup oldParent = (ViewGroup) menuView.getParent(); if (oldParent != null && oldParent != this) { oldParent.removeView(menuView); } addView(menuView, layoutParams); } else { mActionMenuPresenter.setExpandedActionViewsExclusive(false); // Allow full screen width in split mode. mActionMenuPresenter.setWidthLimit( getContext().getResources().getDisplayMetrics().widthPixels, true); // No limit to the item count; use whatever will fit. mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE); // Span the whole width layoutParams.width = LayoutParams.MATCH_PARENT; configPresenters(builder); menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); if (mSplitView != null) { final ViewGroup oldParent = (ViewGroup) menuView.getParent(); if (oldParent != null && oldParent != mSplitView) { oldParent.removeView(menuView); } menuView.setVisibility(getAnimatedVisibility()); mSplitView.addView(menuView, layoutParams); } else { // We'll add this later if we missed it this time. menuView.setLayoutParams(layoutParams); } } mMenuView = menuView; }
public void bindItemView(MenuItemImpl item, MenuView.ItemView itemView) { itemView.initialize(item, 0); //此itemVIew的运行时类型时ActionMenuItemView final ActionMenuView menuView = (ActionMenuView) mMenuView; ActionMenuItemView actionItemView = (ActionMenuItemView) itemView; actionItemView.setItemInvoker(menuView); } public void initialize(MenuItemImpl itemData, int menuType) { mItemData = itemData; setIcon(itemData.getIcon()); setTitle(itemData.getTitleForItemView(this)); // Title only takes effect if there is no icon setId(itemData.getItemId()); setVisibility(itemData.isVisible() ? View.VISIBLE : View.GONE); setEnabled(itemData.isEnabled()); }
if ((cb == null) || !cb.onCreatePanelMenu(st.featureId, st.menu)) { // Ditch the menu created above st.setMenu(null); if (isActionBarMenu && mActionBar != null) { // Don't show it in the action bar either mActionBar.setMenu(null, mActionMenuPresenterCallback); } return false; }
public void inflate(int menuRes, Menu menu) { XmlResourceParser parser = null; try { parser = mContext.getResources().getLayout(menuRes); AttributeSet attrs = Xml.asAttributeSet(parser); parseMenu(parser, attrs, menu); // xml菜单文件的具体解析过程 } catch (XmlPullParserException e) { throw new InflateException("Error inflating menu XML", e); } catch (IOException e) { throw new InflateException("Error inflating menu XML", e); } finally { if (parser != null) parser.close(); } }