FrameworkActionBar.java revision 929eea6bc1824bf98d244550c0984ecf8ea98811
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; 26929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport com.android.internal.R; 2714bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport com.android.internal.app.WindowDecorActionBar; 2814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport com.android.internal.view.menu.MenuBuilder; 29929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport com.android.internal.view.menu.MenuItemImpl; 30929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport com.android.internal.widget.ActionBarAccessor; 3114bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport com.android.internal.widget.ActionBarContainer; 3214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport com.android.internal.widget.ActionBarView; 3314bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport com.android.layoutlib.bridge.android.BridgeContext; 3414bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport com.android.layoutlib.bridge.impl.ResourceHelper; 3514bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport com.android.resources.ResourceType; 3614bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 3714bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport android.app.ActionBar; 3814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport android.app.ActionBar.Tab; 3914bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport android.app.ActionBar.TabListener; 4014bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport android.app.FragmentTransaction; 4114bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport android.content.Context; 42929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport android.content.res.TypedArray; 4314bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport android.graphics.drawable.Drawable; 44929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport android.util.DisplayMetrics; 45929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport android.util.TypedValue; 4614bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport android.view.Gravity; 4714bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport android.view.LayoutInflater; 4814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport android.view.MenuInflater; 49929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport android.view.View; 50929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport android.view.ViewGroup; 51929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport android.widget.FrameLayout; 5214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport android.widget.LinearLayout; 53929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport android.widget.ListAdapter; 54929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport android.widget.ListView; 55929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Guptaimport android.widget.RelativeLayout; 5614bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 5714bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptaimport java.util.ArrayList; 5814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 59929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta/** 60929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta * A layout representing the action bar. 61929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta */ 6214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Guptapublic class ActionBarLayout extends LinearLayout { 6314bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 6414bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta // Store another reference to the context so that we don't have to cast it repeatedly. 65929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @NonNull private final BridgeContext mBridgeContext; 66929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @NonNull private final Context mThemedContext; 67929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 68929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @NonNull private final ActionBar mActionBar; 69929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 70929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Data for Action Bar. 71929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @Nullable private final String mIcon; 72929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @Nullable private final String mTitle; 73929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @Nullable private final String mSubTitle; 7414bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta private final boolean mSplit; 7514bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta private final boolean mShowHomeAsUp; 7614bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta private final int mNavMode; 7714bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 78929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Helper fields. 79929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @NonNull private final MenuBuilder mMenuBuilder; 80929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta private final int mPopupMaxWidth; 81929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @NonNull private final RenderResources res; 82929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @Nullable private final ActionBarView mActionBarView; 83929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @Nullable private FrameLayout mContentRoot; 84929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @NonNull private final ActionBarCallback mCallback; 8514bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 86929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // A fake parent for measuring views. 87929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @Nullable private ViewGroup mMeasureParent; 8814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 89929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta public ActionBarLayout(@NonNull BridgeContext context, @NonNull SessionParams params) { 90929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 91929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta super(context); 9214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta setOrientation(LinearLayout.HORIZONTAL); 9314bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta setGravity(Gravity.CENTER_VERTICAL); 9414bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 95929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Inflate action bar layout. 96929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta LayoutInflater.from(context).inflate(R.layout.screen_action_bar, this, 97929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta true /*attachToRoot*/); 9814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta mActionBar = new WindowDecorActionBar(this); 9914bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 100929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Set contexts. 101929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mBridgeContext = context; 102929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mThemedContext = mActionBar.getThemedContext(); 10314bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 104929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Set data for action bar. 105929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mCallback = params.getProjectCallback().getActionBarCallback(); 106929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mIcon = params.getAppIcon(); 107929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mTitle = params.getAppLabel(); 108929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Split Action Bar when the screen size is narrow and the application requests split action 109929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // bar when narrow. 110929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mSplit = context.getResources().getBoolean(R.bool.split_action_bar_is_narrow) && 111929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mCallback.getSplitActionBarWhenNarrow(); 112929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mNavMode = mCallback.getNavigationMode(); 113929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // TODO: Support Navigation Drawer Indicator. 114929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mShowHomeAsUp = mCallback.getHomeButtonStyle() == HomeButtonStyle.SHOW_HOME_AS_UP; 115929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mSubTitle = mCallback.getSubTitle(); 116929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 117929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 118929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Set helper fields. 119929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mMenuBuilder = new MenuBuilder(mThemedContext); 120929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta res = mBridgeContext.getRenderResources(); 121929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mPopupMaxWidth = Math.max(mBridgeContext.getMetrics().widthPixels / 2, 122929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mThemedContext.getResources().getDimensionPixelSize( 123929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta R.dimen.config_prefDialogWidth)); 124929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mActionBarView = (ActionBarView) findViewById(R.id.action_bar); 125929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mContentRoot = (FrameLayout) findViewById(android.R.id.content); 126929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 127929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta setupActionBar(); 12814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 12914bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 130929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta /** 131929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta * Sets up the action bar by filling the appropriate data. 132929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta */ 133929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta private void setupActionBar() { 134929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Add title and sub title. 13514bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta ResourceValue titleValue = res.findResValue(mTitle, false /*isFramework*/); 13614bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta if (titleValue != null && titleValue.getValue() != null) { 13714bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta mActionBar.setTitle(titleValue.getValue()); 13814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } else { 13914bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta mActionBar.setTitle(mTitle); 14014bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 14114bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta if (mSubTitle != null) { 14214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta mActionBar.setSubtitle(mSubTitle); 14314bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 144929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 145929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Add show home as up icon. 14614bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta if (mShowHomeAsUp) { 14714bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta mActionBar.setDisplayOptions(0xFF, ActionBar.DISPLAY_HOME_AS_UP); 14814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 14914bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 150929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Set the navigation mode. 15114bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta mActionBar.setNavigationMode(mNavMode); 15214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta if (mNavMode == ActionBar.NAVIGATION_MODE_TABS) { 153929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta setupTabs(3); 154929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 155929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 156929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (mActionBarView != null) { 157929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // If the action bar style doesn't specify an icon, set the icon obtained from the session 158929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // params. 159929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (!mActionBarView.hasIcon() && mIcon != null) { 160929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta Drawable iconDrawable = getDrawable(mIcon, false /*isFramework*/); 161929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (iconDrawable != null) { 162929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mActionBar.setIcon(iconDrawable); 163929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 164929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 165929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 166929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Set action bar to be split, if needed. 167929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mActionBarView.setSplitView((ActionBarContainer) findViewById(R.id.split_action_bar)); 168929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mActionBarView.setSplitActionBar(mSplit); 169929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 170929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta inflateMenus(); 17114bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 17214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 17314bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 174929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta /** 175929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta * Gets the menus to add to the action bar from the callback, resolves them, inflates them and 176929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta * adds them to the action bar. 177929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta */ 178929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta private void inflateMenus() { 179929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (mActionBarView == null) { 18014bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta return; 18114bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 182929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta final MenuInflater inflater = new MenuInflater(mThemedContext); 183929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta for (String name : mCallback.getMenuIdNames()) { 184929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (mBridgeContext.getRenderResources().getProjectResource(ResourceType.MENU, name) 185929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta != null) { 186929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta int id = mBridgeContext.getProjectResourceValue(ResourceType.MENU, name, -1); 187929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (id > -1) { 188929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta inflater.inflate(id, mMenuBuilder); 189929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 190929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 19114bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 192929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mActionBarView.setMenu(mMenuBuilder, null /*callback*/); 19314bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 19414bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 19514bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta // TODO: Use an adapter, like List View to set up tabs. 196929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta private void setupTabs(int num) { 19714bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta for (int i = 1; i <= num; i++) { 198929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta Tab tab = mActionBar.newTab().setText("Tab" + i).setTabListener(new TabListener() { 19914bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta @Override 20014bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta public void onTabUnselected(Tab t, FragmentTransaction ft) { 20114bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta // pass 20214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 20314bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta @Override 20414bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta public void onTabSelected(Tab t, FragmentTransaction ft) { 20514bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta // pass 20614bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 20714bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta @Override 20814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta public void onTabReselected(Tab t, FragmentTransaction ft) { 20914bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta // pass 21014bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 21114bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta }); 21214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta mActionBar.addTab(tab); 21314bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 21414bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 21514bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta 216929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @Nullable 217929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta private Drawable getDrawable(@NonNull String name, boolean isFramework) { 21814bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta ResourceValue value = res.findResValue(name, isFramework); 21914bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta value = res.resolveResValue(value); 22014bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta if (value != null) { 221929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta return ResourceHelper.getDrawable(value, mBridgeContext); 22214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 22314bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta return null; 22414bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta } 225929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 226929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta /** 227929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta * Creates a Popup and adds it to the content frame. It also adds another {@link FrameLayout} to 228929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta * the content frame which shall serve as the new content root. 229929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta */ 230929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta public void createMenuPopup() { 231929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta assert mContentRoot != null && findViewById(android.R.id.content) == mContentRoot 232929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta : "Action Bar Menus have already been created."; 233929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 234929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (!isOverflowPopupNeeded()) { 235929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta return; 236929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 237929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 238929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Create a layout to hold the menus and the user's content. 239929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta RelativeLayout layout = new RelativeLayout(mThemedContext); 240929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 241929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta LayoutParams.MATCH_PARENT)); 242929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mContentRoot.addView(layout); 243929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Create a layout for the user's content. 244929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta FrameLayout contentRoot = new FrameLayout(mBridgeContext); 245929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta contentRoot.setLayoutParams(new LayoutParams( 246929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); 247929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Add contentRoot and menus to the layout. 248929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layout.addView(contentRoot); 249929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layout.addView(createMenuView()); 250929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // ContentRoot is now the view we just created. 251929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mContentRoot = contentRoot; 252929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 253929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 254929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta /** 255929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta * Returns a {@link LinearLayout} containing the menu list view to be embedded in a 256929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta * {@link RelativeLayout} 257929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta */ 258929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @NonNull 259929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta private View createMenuView() { 260929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta DisplayMetrics metrics = mBridgeContext.getMetrics(); 261929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta OverflowMenuAdapter adapter = new OverflowMenuAdapter(mMenuBuilder, mThemedContext); 262929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 263929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta LinearLayout layout = new LinearLayout(mThemedContext); 264929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams( 265929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta measureContentWidth(adapter), LayoutParams.WRAP_CONTENT); 266929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layoutParams.addRule(RelativeLayout.ALIGN_PARENT_END); 267929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (mSplit) { 268929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); 269929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // TODO: Find correct value instead of hardcoded 10dp. 270929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layoutParams.bottomMargin = getPixelValue("-10dp", metrics); 271929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } else { 272929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layoutParams.topMargin = getPixelValue("-10dp", metrics); 273929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 274929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layout.setLayoutParams(layoutParams); 275929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta final TypedArray a = mThemedContext.obtainStyledAttributes(null, 276929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta R.styleable.PopupWindow, R.attr.popupMenuStyle, 0); 277929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layout.setBackground(a.getDrawable(R.styleable.PopupWindow_popupBackground)); 278929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layout.setDividerDrawable(a.getDrawable(R.attr.actionBarDivider)); 279929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta a.recycle(); 280929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layout.setOrientation(LinearLayout.VERTICAL); 281929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layout.setDividerPadding(getPixelValue("12dp", metrics)); 282929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE); 283929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 284929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta ListView listView = new ListView(mThemedContext, null, R.attr.dropDownListViewStyle); 285929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta listView.setAdapter(adapter); 286929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta layout.addView(listView); 287929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta return layout; 288929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 289929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 290929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta private boolean isOverflowPopupNeeded() { 291929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta boolean needed = mCallback.isOverflowPopupNeeded(); 292929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (!needed) { 293929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta return false; 294929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 295929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Copied from android.widget.ActionMenuPresenter.updateMenuView() 296929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta ArrayList<MenuItemImpl> menus = mMenuBuilder.getNonActionItems(); 297929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (ActionBarAccessor.getActionMenuPresenter(mActionBarView).isOverflowReserved() && 298929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta menus != null) { 299929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta final int count = menus.size(); 300929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (count == 1) { 301929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta needed = !menus.get(0).isActionViewExpanded(); 302929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } else { 303929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta needed = count > 0; 304929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 305929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 306929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta return needed; 307929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 308929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 309929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta @Nullable 310929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta public FrameLayout getContentRoot() { 311929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta return mContentRoot; 312929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 313929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 314929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Copied from com.android.internal.view.menu.MenuPopHelper.measureContentWidth() 315929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta private int measureContentWidth(@NonNull ListAdapter adapter) { 316929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta // Menus don't tend to be long, so this is more sane than it looks. 317929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta int maxWidth = 0; 318929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta View itemView = null; 319929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta int itemType = 0; 320929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 321929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 322929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 323929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta final int count = adapter.getCount(); 324929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta for (int i = 0; i < count; i++) { 325929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta final int positionType = adapter.getItemViewType(i); 326929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (positionType != itemType) { 327929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta itemType = positionType; 328929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta itemView = null; 329929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 330929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 331929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (mMeasureParent == null) { 332929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta mMeasureParent = new FrameLayout(mThemedContext); 333929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 334929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 335929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta itemView = adapter.getView(i, itemView, mMeasureParent); 336929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta itemView.measure(widthMeasureSpec, heightMeasureSpec); 337929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 338929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta final int itemWidth = itemView.getMeasuredWidth(); 339929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta if (itemWidth >= mPopupMaxWidth) { 340929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta return mPopupMaxWidth; 341929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } else if (itemWidth > maxWidth) { 342929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta maxWidth = itemWidth; 343929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 344929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 345929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 346929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta return maxWidth; 347929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 348929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 349929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta private int getPixelValue(@NonNull String value, @NonNull DisplayMetrics metrics) { 350929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta TypedValue typedValue = ResourceHelper.getValue(null, value, false /*requireUnit*/); 351929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta return (int) typedValue.getDimension(metrics); 352929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta } 353929eea6bc1824bf98d244550c0984ecf8ea98811Deepanshu Gupta 35414bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta} 355