ActionBarLayout.java revision 674af92fd3a618695448ff88568b03390e90bc66
114bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta/* 214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta * Copyright (C) 2014 The Android Open Source Project 314bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta * 414bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta * Licensed under the Apache License, Version 2.0 (the "License"); 514bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta * you may not use this file except in compliance with the License. 614bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta * You may obtain a copy of the License at 714bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta * 814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta * http://www.apache.org/licenses/LICENSE-2.0 914bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta * 1014bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta * Unless required by applicable law or agreed to in writing, software 1114bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta * distributed under the License is distributed on an "AS IS" BASIS, 1214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1314bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta * See the License for the specific language governing permissions and 1414bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta * limitations under the License. 1514bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta */ 1614bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 1714bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptapackage com.android.layoutlib.bridge.bars; 1814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 19929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport com.android.annotations.NonNull; 20929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport com.android.annotations.Nullable; 2114bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport com.android.ide.common.rendering.api.ActionBarCallback; 2214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport com.android.ide.common.rendering.api.ActionBarCallback.HomeButtonStyle; 2314bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport com.android.ide.common.rendering.api.RenderResources; 2414bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport com.android.ide.common.rendering.api.ResourceValue; 2514bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport com.android.ide.common.rendering.api.SessionParams; 26674af92fd3a618695448ff88568b03390e90bc66Deepanshu Guptaimport com.android.ide.common.rendering.api.SystemViewCookie; 27929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport com.android.internal.R; 2814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport com.android.internal.app.WindowDecorActionBar; 29674af92fd3a618695448ff88568b03390e90bc66Deepanshu Guptaimport com.android.internal.util.Predicate; 3014bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport com.android.internal.view.menu.MenuBuilder; 31929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport com.android.internal.view.menu.MenuItemImpl; 32929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport com.android.internal.widget.ActionBarAccessor; 3314bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport com.android.internal.widget.ActionBarContainer; 3414bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport com.android.internal.widget.ActionBarView; 3514bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport com.android.layoutlib.bridge.android.BridgeContext; 3614bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport com.android.layoutlib.bridge.impl.ResourceHelper; 3714bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport com.android.resources.ResourceType; 3814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 3914bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport android.app.ActionBar; 4014bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport android.app.ActionBar.Tab; 4114bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport android.app.ActionBar.TabListener; 4214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport android.app.FragmentTransaction; 4314bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport android.content.Context; 44929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport android.content.res.TypedArray; 4514bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport android.graphics.drawable.Drawable; 46929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport android.util.DisplayMetrics; 47929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport android.util.TypedValue; 4814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport android.view.Gravity; 4914bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport android.view.LayoutInflater; 5014bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport android.view.MenuInflater; 51929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport android.view.View; 52929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport android.view.ViewGroup; 53929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport android.widget.FrameLayout; 5414bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport android.widget.LinearLayout; 55929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport android.widget.ListAdapter; 56929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport android.widget.ListView; 57929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport android.widget.RelativeLayout; 5814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 5914bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport java.util.ArrayList; 6014bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 61674af92fd3a618695448ff88568b03390e90bc66Deepanshu Guptaimport static com.android.ide.common.rendering.api.SystemViewCookie.ACTION_BAR_OVERFLOW; 62674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta 63929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta/** 64929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta * A layout representing the action bar. 65929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta */ 6614bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptapublic class ActionBarLayout extends LinearLayout { 6714bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 6814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta // Store another reference to the context so that we don't have to cast it repeatedly. 69929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @NonNull private final BridgeContext mBridgeContext; 70929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @NonNull private final Context mThemedContext; 71929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 72929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @NonNull private final ActionBar mActionBar; 73929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 74929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Data for Action Bar. 75929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @Nullable private final String mIcon; 76929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @Nullable private final String mTitle; 77929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @Nullable private final String mSubTitle; 7814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta private final boolean mSplit; 7914bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta private final boolean mShowHomeAsUp; 8014bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta private final int mNavMode; 8114bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 82929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Helper fields. 83929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @NonNull private final MenuBuilder mMenuBuilder; 84929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta private final int mPopupMaxWidth; 85929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @NonNull private final RenderResources res; 86929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @Nullable private final ActionBarView mActionBarView; 87929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @Nullable private FrameLayout mContentRoot; 88929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @NonNull private final ActionBarCallback mCallback; 8914bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 90929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // A fake parent for measuring views. 91929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @Nullable private ViewGroup mMeasureParent; 9214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 93929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta public ActionBarLayout(@NonNull BridgeContext context, @NonNull SessionParams params) { 94929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 95929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta super(context); 9614bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta setOrientation(LinearLayout.HORIZONTAL); 9714bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta setGravity(Gravity.CENTER_VERTICAL); 9814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 99929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Inflate action bar layout. 100929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta LayoutInflater.from(context).inflate(R.layout.screen_action_bar, this, 101929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta true /*attachToRoot*/); 10214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta mActionBar = new WindowDecorActionBar(this); 10314bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 104929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Set contexts. 105929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mBridgeContext = context; 106929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mThemedContext = mActionBar.getThemedContext(); 10714bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 108929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Set data for action bar. 109929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mCallback = params.getProjectCallback().getActionBarCallback(); 110929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mIcon = params.getAppIcon(); 111929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mTitle = params.getAppLabel(); 112929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Split Action Bar when the screen size is narrow and the application requests split action 113929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // bar when narrow. 114929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mSplit = context.getResources().getBoolean(R.bool.split_action_bar_is_narrow) && 115929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mCallback.getSplitActionBarWhenNarrow(); 116929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mNavMode = mCallback.getNavigationMode(); 117929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // TODO: Support Navigation Drawer Indicator. 118929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mShowHomeAsUp = mCallback.getHomeButtonStyle() == HomeButtonStyle.SHOW_HOME_AS_UP; 119929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mSubTitle = mCallback.getSubTitle(); 120929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 121929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 122929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Set helper fields. 123929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mMenuBuilder = new MenuBuilder(mThemedContext); 124929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta res = mBridgeContext.getRenderResources(); 125929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mPopupMaxWidth = Math.max(mBridgeContext.getMetrics().widthPixels / 2, 126929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mThemedContext.getResources().getDimensionPixelSize( 127929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta R.dimen.config_prefDialogWidth)); 128929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mActionBarView = (ActionBarView) findViewById(R.id.action_bar); 129929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mContentRoot = (FrameLayout) findViewById(android.R.id.content); 130929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 131929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta setupActionBar(); 13214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 13314bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 134929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta /** 135929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta * Sets up the action bar by filling the appropriate data. 136929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta */ 137929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta private void setupActionBar() { 138929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Add title and sub title. 13914bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta ResourceValue titleValue = res.findResValue(mTitle, false /*isFramework*/); 14014bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta if (titleValue != null && titleValue.getValue() != null) { 14114bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta mActionBar.setTitle(titleValue.getValue()); 14214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } else { 14314bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta mActionBar.setTitle(mTitle); 14414bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 14514bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta if (mSubTitle != null) { 14614bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta mActionBar.setSubtitle(mSubTitle); 14714bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 148929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 149929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Add show home as up icon. 15014bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta if (mShowHomeAsUp) { 15114bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta mActionBar.setDisplayOptions(0xFF, ActionBar.DISPLAY_HOME_AS_UP); 15214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 15314bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 154929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Set the navigation mode. 15514bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta mActionBar.setNavigationMode(mNavMode); 15614bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta if (mNavMode == ActionBar.NAVIGATION_MODE_TABS) { 157929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta setupTabs(3); 158929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 159929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 160929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (mActionBarView != null) { 161929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // If the action bar style doesn't specify an icon, set the icon obtained from the session 162929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // params. 163929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (!mActionBarView.hasIcon() && mIcon != null) { 164929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta Drawable iconDrawable = getDrawable(mIcon, false /*isFramework*/); 165929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (iconDrawable != null) { 166929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mActionBar.setIcon(iconDrawable); 167929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 168929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 169929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 170929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Set action bar to be split, if needed. 171674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta ActionBarContainer splitView = (ActionBarContainer) findViewById(R.id.split_action_bar); 172674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta mActionBarView.setSplitView(splitView); 173929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mActionBarView.setSplitActionBar(mSplit); 174929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 175929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta inflateMenus(); 176674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta 177674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta // Find if the Overflow Menu Button (the three dots) exists. If yes, 178674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta // add the view cookie. 179674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta Predicate<View> overflowMenuButtonTest = new Predicate<View>() { 180674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta @Override 181674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta public boolean apply(View view) { 182674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta return view.getClass().getName() 183674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta .equals("android.widget.ActionMenuPresenter$OverflowMenuButton"); 184674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta } 185674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta }; 186674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta View overflowMenu = null; 187674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta if (mSplit) { 188674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta if (splitView != null) { 189674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta overflowMenu = splitView.findViewByPredicate(overflowMenuButtonTest); 190674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta } 191674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta } 192674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta else { 193674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta overflowMenu = mActionBarView.findViewByPredicate(overflowMenuButtonTest); 194674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta } 195674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta if (overflowMenu != null) { 196674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta mBridgeContext.addViewKey(overflowMenu, new SystemViewCookie(ACTION_BAR_OVERFLOW)); 197674af92fd3a618695448ff88568b03390e90bc66Deepanshu Gupta } 19814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 19914bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 20014bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 201929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta /** 202929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta * Gets the menus to add to the action bar from the callback, resolves them, inflates them and 203929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta * adds them to the action bar. 204929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta */ 205929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta private void inflateMenus() { 206929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (mActionBarView == null) { 20714bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta return; 20814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 209929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta final MenuInflater inflater = new MenuInflater(mThemedContext); 210929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta for (String name : mCallback.getMenuIdNames()) { 211929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (mBridgeContext.getRenderResources().getProjectResource(ResourceType.MENU, name) 212929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta != null) { 213929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta int id = mBridgeContext.getProjectResourceValue(ResourceType.MENU, name, -1); 214929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (id > -1) { 215929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta inflater.inflate(id, mMenuBuilder); 216929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 217929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 21814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 219929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mActionBarView.setMenu(mMenuBuilder, null /*callback*/); 22014bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 22114bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 22214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta // TODO: Use an adapter, like List View to set up tabs. 223929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta private void setupTabs(int num) { 22414bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta for (int i = 1; i <= num; i++) { 225929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta Tab tab = mActionBar.newTab().setText("Tab" + i).setTabListener(new TabListener() { 22614bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta @Override 22714bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta public void onTabUnselected(Tab t, FragmentTransaction ft) { 22814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta // pass 22914bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 23014bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta @Override 23114bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta public void onTabSelected(Tab t, FragmentTransaction ft) { 23214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta // pass 23314bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 23414bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta @Override 23514bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta public void onTabReselected(Tab t, FragmentTransaction ft) { 23614bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta // pass 23714bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 23814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta }); 23914bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta mActionBar.addTab(tab); 24014bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 24114bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 24214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 243929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @Nullable 244929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta private Drawable getDrawable(@NonNull String name, boolean isFramework) { 24514bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta ResourceValue value = res.findResValue(name, isFramework); 24614bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta value = res.resolveResValue(value); 24714bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta if (value != null) { 248929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta return ResourceHelper.getDrawable(value, mBridgeContext); 24914bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 25014bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta return null; 25114bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 252929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 253929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta /** 254929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta * Creates a Popup and adds it to the content frame. It also adds another {@link FrameLayout} to 255929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta * the content frame which shall serve as the new content root. 256929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta */ 257929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta public void createMenuPopup() { 258929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta assert mContentRoot != null && findViewById(android.R.id.content) == mContentRoot 259929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta : "Action Bar Menus have already been created."; 260929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 261929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (!isOverflowPopupNeeded()) { 262929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta return; 263929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 264929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 265929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Create a layout to hold the menus and the user's content. 266929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta RelativeLayout layout = new RelativeLayout(mThemedContext); 267929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 268929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta LayoutParams.MATCH_PARENT)); 269929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mContentRoot.addView(layout); 270929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Create a layout for the user's content. 271929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta FrameLayout contentRoot = new FrameLayout(mBridgeContext); 272929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta contentRoot.setLayoutParams(new LayoutParams( 273929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); 274929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Add contentRoot and menus to the layout. 275929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layout.addView(contentRoot); 276929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layout.addView(createMenuView()); 277929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // ContentRoot is now the view we just created. 278929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mContentRoot = contentRoot; 279929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 280929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 281929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta /** 282929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta * Returns a {@link LinearLayout} containing the menu list view to be embedded in a 283929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta * {@link RelativeLayout} 284929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta */ 285929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @NonNull 286929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta private View createMenuView() { 287929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta DisplayMetrics metrics = mBridgeContext.getMetrics(); 288929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta OverflowMenuAdapter adapter = new OverflowMenuAdapter(mMenuBuilder, mThemedContext); 289929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 290929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta LinearLayout layout = new LinearLayout(mThemedContext); 291929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams( 292929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta measureContentWidth(adapter), LayoutParams.WRAP_CONTENT); 293929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layoutParams.addRule(RelativeLayout.ALIGN_PARENT_END); 294929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (mSplit) { 295929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); 296929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // TODO: Find correct value instead of hardcoded 10dp. 297929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layoutParams.bottomMargin = getPixelValue("-10dp", metrics); 298929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } else { 299929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layoutParams.topMargin = getPixelValue("-10dp", metrics); 300929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 301929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layout.setLayoutParams(layoutParams); 302929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta final TypedArray a = mThemedContext.obtainStyledAttributes(null, 303929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta R.styleable.PopupWindow, R.attr.popupMenuStyle, 0); 304929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layout.setBackground(a.getDrawable(R.styleable.PopupWindow_popupBackground)); 305929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layout.setDividerDrawable(a.getDrawable(R.attr.actionBarDivider)); 306929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta a.recycle(); 307929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layout.setOrientation(LinearLayout.VERTICAL); 308929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layout.setDividerPadding(getPixelValue("12dp", metrics)); 309929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE); 310929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 311929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta ListView listView = new ListView(mThemedContext, null, R.attr.dropDownListViewStyle); 312929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta listView.setAdapter(adapter); 313929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layout.addView(listView); 314929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta return layout; 315929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 316929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 317929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta private boolean isOverflowPopupNeeded() { 318929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta boolean needed = mCallback.isOverflowPopupNeeded(); 319929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (!needed) { 320929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta return false; 321929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 322929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Copied from android.widget.ActionMenuPresenter.updateMenuView() 323929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta ArrayList<MenuItemImpl> menus = mMenuBuilder.getNonActionItems(); 324929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (ActionBarAccessor.getActionMenuPresenter(mActionBarView).isOverflowReserved() && 325929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta menus != null) { 326929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta final int count = menus.size(); 327929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (count == 1) { 328929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta needed = !menus.get(0).isActionViewExpanded(); 329929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } else { 330929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta needed = count > 0; 331929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 332929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 333929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta return needed; 334929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 335929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 336929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @Nullable 337929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta public FrameLayout getContentRoot() { 338929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta return mContentRoot; 339929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 340929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 341929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Copied from com.android.internal.view.menu.MenuPopHelper.measureContentWidth() 342929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta private int measureContentWidth(@NonNull ListAdapter adapter) { 343929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Menus don't tend to be long, so this is more sane than it looks. 344929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta int maxWidth = 0; 345929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta View itemView = null; 346929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta int itemType = 0; 347929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 348929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 349929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 350929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta final int count = adapter.getCount(); 351929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta for (int i = 0; i < count; i++) { 352929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta final int positionType = adapter.getItemViewType(i); 353929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (positionType != itemType) { 354929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta itemType = positionType; 355929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta itemView = null; 356929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 357929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 358929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (mMeasureParent == null) { 359929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mMeasureParent = new FrameLayout(mThemedContext); 360929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 361929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 362929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta itemView = adapter.getView(i, itemView, mMeasureParent); 363929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta itemView.measure(widthMeasureSpec, heightMeasureSpec); 364929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 365929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta final int itemWidth = itemView.getMeasuredWidth(); 366929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (itemWidth >= mPopupMaxWidth) { 367929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta return mPopupMaxWidth; 368929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } else if (itemWidth > maxWidth) { 369929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta maxWidth = itemWidth; 370929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 371929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 372929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 373929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta return maxWidth; 374929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 375929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 376929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta private int getPixelValue(@NonNull String value, @NonNull DisplayMetrics metrics) { 377929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta TypedValue typedValue = ResourceHelper.getValue(null, value, false /*requireUnit*/); 378929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta return (int) typedValue.getDimension(metrics); 379929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 380929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 38114bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta} 382