am f7e57949: Overflow menu popup for Action Bar in Layoutlib [DO NOT MERGE]
* commit 'f7e5794990831df87d4097126f6d24455da50efe': Overflow menu popup for Action Bar in Layoutlib [DO NOT MERGE]
This commit is contained in:
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<include layout="@android:layout/screen_action_bar" />
|
||||
|
||||
</merge>
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.android.internal.view.menu;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* To access non public members of {@link MenuBuilder}
|
||||
*/
|
||||
public class MenuBuilderAccessor {
|
||||
public static ArrayList<MenuItemImpl> getNonActionItems(MenuBuilder builder) {
|
||||
return builder.getNonActionItems();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.widget;
|
||||
|
||||
import com.android.internal.view.menu.ActionMenuPresenter;
|
||||
|
||||
/**
|
||||
* To access non public members of AbsActionBarView
|
||||
*/
|
||||
public class ActionBarAccessor {
|
||||
|
||||
/**
|
||||
* Returns the {@link ActionMenuPresenter} associated with the {@link AbsActionBarView}
|
||||
*/
|
||||
public static ActionMenuPresenter getActionMenuPresenter(AbsActionBarView view) {
|
||||
return view.mActionMenuPresenter;
|
||||
}
|
||||
}
|
||||
@@ -16,108 +16,122 @@
|
||||
|
||||
package com.android.layoutlib.bridge.bars;
|
||||
|
||||
import com.android.annotations.Nullable;
|
||||
import com.android.ide.common.rendering.api.ActionBarCallback;
|
||||
import com.android.ide.common.rendering.api.ActionBarCallback.HomeButtonStyle;
|
||||
import com.android.ide.common.rendering.api.RenderResources;
|
||||
import com.android.ide.common.rendering.api.ResourceValue;
|
||||
import com.android.ide.common.rendering.api.SessionParams;
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.app.ActionBarImpl;
|
||||
import com.android.internal.view.menu.MenuBuilder;
|
||||
import com.android.internal.view.menu.MenuBuilderAccessor;
|
||||
import com.android.internal.view.menu.MenuItemImpl;
|
||||
import com.android.internal.widget.ActionBarAccessor;
|
||||
import com.android.internal.widget.ActionBarContainer;
|
||||
import com.android.internal.widget.ActionBarView;
|
||||
import com.android.layoutlib.bridge.Bridge;
|
||||
import com.android.layoutlib.bridge.android.BridgeContext;
|
||||
import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
|
||||
import com.android.layoutlib.bridge.impl.ParserFactory;
|
||||
import com.android.layoutlib.bridge.impl.ResourceHelper;
|
||||
import com.android.resources.ResourceType;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import android.app.ActionBar;
|
||||
import android.app.ActionBar.Tab;
|
||||
import android.app.ActionBar.TabListener;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A layout representing the action bar.
|
||||
*/
|
||||
public class ActionBarLayout extends LinearLayout {
|
||||
|
||||
// Store another reference to the context so that we don't have to cast it repeatedly.
|
||||
@SuppressWarnings("hiding")
|
||||
private final BridgeContext mContext;
|
||||
private final BridgeContext mBridgeContext;
|
||||
private final Context mThemedContext;
|
||||
|
||||
private final ActionBar mActionBar;
|
||||
private final String mIcon;
|
||||
private final String mTitle;
|
||||
private final String mSubTitle;
|
||||
|
||||
// Data for Action Bar.
|
||||
@Nullable private final String mIcon;
|
||||
@Nullable private final String mTitle;
|
||||
@Nullable private final String mSubTitle;
|
||||
private final boolean mSplit;
|
||||
private final boolean mShowHomeAsUp;
|
||||
private final List<Integer> mMenuIds;
|
||||
private final MenuBuilder mMenuBuilder;
|
||||
private final int mNavMode;
|
||||
|
||||
public ActionBarLayout(BridgeContext context, SessionParams params)
|
||||
throws XmlPullParserException {
|
||||
// Helper fields.
|
||||
private final MenuBuilder mMenuBuilder;
|
||||
private final int mPopupMaxWidth;
|
||||
private final RenderResources res;
|
||||
@Nullable private final ActionBarView mActionBarView;
|
||||
@Nullable private FrameLayout mContentRoot;
|
||||
private final ActionBarCallback mCallback;
|
||||
|
||||
// A fake parent for measuring views.
|
||||
@Nullable private ViewGroup mMeasureParent;
|
||||
|
||||
public ActionBarLayout(BridgeContext context, SessionParams params) {
|
||||
|
||||
super(context);
|
||||
mIcon = params.getAppIcon();
|
||||
mTitle = params.getAppLabel();
|
||||
mContext = context;
|
||||
mMenuIds = new ArrayList<Integer>();
|
||||
|
||||
ActionBarCallback callback = params.getProjectCallback().getActionBarCallback();
|
||||
mSplit = callback.getSplitActionBarWhenNarrow() &
|
||||
context.getResources().getBoolean(
|
||||
com.android.internal.R.bool.split_action_bar_is_narrow);
|
||||
mNavMode = callback.getNavigationMode();
|
||||
// TODO: Support Navigation Drawer Indicator.
|
||||
mShowHomeAsUp = callback.getHomeButtonStyle() == HomeButtonStyle.SHOW_HOME_AS_UP;
|
||||
mSubTitle = callback.getSubTitle();
|
||||
|
||||
fillMenuIds(callback.getMenuIdNames());
|
||||
mMenuBuilder = new MenuBuilder(mContext);
|
||||
|
||||
setOrientation(LinearLayout.HORIZONTAL);
|
||||
setGravity(Gravity.CENTER_VERTICAL);
|
||||
|
||||
LayoutInflater inflater = (LayoutInflater) context.getSystemService(
|
||||
Context.LAYOUT_INFLATER_SERVICE);
|
||||
XmlPullParser parser = ParserFactory.create(
|
||||
getClass().getResourceAsStream("/bars/action_bar.xml"), "action_bar.xml");
|
||||
BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(
|
||||
parser, context, false /*platformFile*/);
|
||||
try {
|
||||
inflater.inflate(bridgeParser, this, true /*attachToRoot*/);
|
||||
} finally {
|
||||
bridgeParser.ensurePopped();
|
||||
}
|
||||
// Inflate action bar layout.
|
||||
LayoutInflater.from(context).inflate(R.layout.screen_action_bar, this,
|
||||
true /*attachToRoot*/);
|
||||
mActionBar = new ActionBarImpl(this);
|
||||
|
||||
setUpActionBar();
|
||||
// Set contexts.
|
||||
mBridgeContext = context;
|
||||
mThemedContext = mActionBar.getThemedContext();
|
||||
|
||||
// Set data for action bar.
|
||||
mCallback = params.getProjectCallback().getActionBarCallback();
|
||||
mIcon = params.getAppIcon();
|
||||
mTitle = params.getAppLabel();
|
||||
// Split Action Bar when the screen size is narrow and the application requests split action
|
||||
// bar when narrow.
|
||||
mSplit = context.getResources().getBoolean(R.bool.split_action_bar_is_narrow) &&
|
||||
mCallback.getSplitActionBarWhenNarrow();
|
||||
mNavMode = mCallback.getNavigationMode();
|
||||
// TODO: Support Navigation Drawer Indicator.
|
||||
mShowHomeAsUp = mCallback.getHomeButtonStyle() == HomeButtonStyle.SHOW_HOME_AS_UP;
|
||||
mSubTitle = mCallback.getSubTitle();
|
||||
|
||||
|
||||
// Set helper fields.
|
||||
mMenuBuilder = new MenuBuilder(mThemedContext);
|
||||
res = mBridgeContext.getRenderResources();
|
||||
mPopupMaxWidth = Math.max(mBridgeContext.getMetrics().widthPixels / 2,
|
||||
mThemedContext.getResources().getDimensionPixelSize(
|
||||
R.dimen.config_prefDialogWidth));
|
||||
mActionBarView = (ActionBarView) findViewById(R.id.action_bar);
|
||||
mContentRoot = (FrameLayout) findViewById(android.R.id.content);
|
||||
|
||||
setupActionBar();
|
||||
}
|
||||
|
||||
private void fillMenuIds(List<String> menuIdNames) {
|
||||
for (String name : menuIdNames) {
|
||||
int id = mContext.getProjectResourceValue(ResourceType.MENU, name, -1);
|
||||
if (id > -1) {
|
||||
mMenuIds.add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpActionBar() {
|
||||
RenderResources res = mContext.getRenderResources();
|
||||
Drawable iconDrawable = getDrawable(res, mIcon, false /*isFramework*/);
|
||||
if (iconDrawable != null) {
|
||||
mActionBar.setIcon(iconDrawable);
|
||||
}
|
||||
/**
|
||||
* Sets up the action bar by filling the appropriate data.
|
||||
*/
|
||||
private void setupActionBar() {
|
||||
// Add title and sub title.
|
||||
ResourceValue titleValue = res.findResValue(mTitle, false /*isFramework*/);
|
||||
if (titleValue != null && titleValue.getValue() != null) {
|
||||
mActionBar.setTitle(titleValue.getValue());
|
||||
@@ -127,41 +141,62 @@ public class ActionBarLayout extends LinearLayout {
|
||||
if (mSubTitle != null) {
|
||||
mActionBar.setSubtitle(mSubTitle);
|
||||
}
|
||||
ActionBarView actionBarView = (ActionBarView) findViewById(
|
||||
Bridge.getResourceId(ResourceType.ID, "action_bar"));
|
||||
actionBarView.setSplitView((ActionBarContainer) findViewById(
|
||||
Bridge.getResourceId(ResourceType.ID, "split_action_bar")));
|
||||
actionBarView.setSplitActionBar(mSplit);
|
||||
|
||||
// Add show home as up icon.
|
||||
if (mShowHomeAsUp) {
|
||||
mActionBar.setDisplayOptions(0xFF, ActionBar.DISPLAY_HOME_AS_UP);
|
||||
}
|
||||
setUpActionMenus();
|
||||
|
||||
// Set the navigation mode.
|
||||
mActionBar.setNavigationMode(mNavMode);
|
||||
if (mNavMode == ActionBar.NAVIGATION_MODE_TABS) {
|
||||
setUpTabs(3);
|
||||
setupTabs(3);
|
||||
}
|
||||
|
||||
// Ideally we should get the icon from the mThemedContext using R.styleable.ActionBar_icon.
|
||||
// But for simplicity, we are using the icon passed from the session params. This has been
|
||||
// fixed in API 19.
|
||||
if (mIcon != null) {
|
||||
Drawable iconDrawable = getDrawable(mIcon, false /*isFramework*/);
|
||||
if (iconDrawable != null) {
|
||||
mActionBar.setIcon(iconDrawable);
|
||||
}
|
||||
}
|
||||
|
||||
if (mActionBarView != null) {
|
||||
// Set action bar to be split, if needed.
|
||||
mActionBarView.setSplitView((ActionBarContainer) findViewById(R.id.split_action_bar));
|
||||
mActionBarView.setSplitActionBar(mSplit);
|
||||
|
||||
inflateMenus();
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpActionMenus() {
|
||||
if (mMenuIds == null) {
|
||||
/**
|
||||
* Gets the menus to add to the action bar from the callback, resolves them, inflates them and
|
||||
* adds them to the action bar.
|
||||
*/
|
||||
private void inflateMenus() {
|
||||
if (mActionBarView == null) {
|
||||
return;
|
||||
}
|
||||
ActionBarView actionBarView = (ActionBarView) findViewById(Bridge.getResourceId(
|
||||
ResourceType.ID, "action_bar"));
|
||||
final MenuInflater inflater = new MenuInflater(mActionBar.getThemedContext());
|
||||
for (int id : mMenuIds) {
|
||||
inflater.inflate(id, mMenuBuilder);
|
||||
final MenuInflater inflater = new MenuInflater(mThemedContext);
|
||||
for (String name : mCallback.getMenuIdNames()) {
|
||||
if (mBridgeContext.getRenderResources().getProjectResource(ResourceType.MENU, name)
|
||||
!= null) {
|
||||
int id = mBridgeContext.getProjectResourceValue(ResourceType.MENU, name, -1);
|
||||
if (id > -1) {
|
||||
inflater.inflate(id, mMenuBuilder);
|
||||
}
|
||||
}
|
||||
}
|
||||
actionBarView.setMenu(mMenuBuilder, null /*callback*/);
|
||||
mActionBarView.setMenu(mMenuBuilder, null /*callback*/);
|
||||
}
|
||||
|
||||
// TODO: Use an adapter, like List View to set up tabs.
|
||||
private void setUpTabs(int num) {
|
||||
private void setupTabs(int num) {
|
||||
for (int i = 1; i <= num; i++) {
|
||||
Tab tab = mActionBar.newTab()
|
||||
.setText("Tab" + i)
|
||||
.setTabListener(new TabListener() {
|
||||
Tab tab = mActionBar.newTab().setText("Tab" + i).setTabListener(new TabListener() {
|
||||
@Override
|
||||
public void onTabUnselected(Tab t, FragmentTransaction ft) {
|
||||
// pass
|
||||
@@ -179,12 +214,141 @@ public class ActionBarLayout extends LinearLayout {
|
||||
}
|
||||
}
|
||||
|
||||
private Drawable getDrawable(RenderResources res, String name, boolean isFramework) {
|
||||
@Nullable
|
||||
private Drawable getDrawable(String name, boolean isFramework) {
|
||||
ResourceValue value = res.findResValue(name, isFramework);
|
||||
value = res.resolveResValue(value);
|
||||
if (value != null) {
|
||||
return ResourceHelper.getDrawable(value, mContext);
|
||||
return ResourceHelper.getDrawable(value, mBridgeContext);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Popup and adds it to the content frame. It also adds another {@link FrameLayout} to
|
||||
* the content frame which shall serve as the new content root.
|
||||
*/
|
||||
public void createMenuPopup() {
|
||||
assert mContentRoot != null && findViewById(android.R.id.content) == mContentRoot
|
||||
: "Action Bar Menus have already been created.";
|
||||
|
||||
if (!isOverflowPopupNeeded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a layout to hold the menus and the user's content.
|
||||
RelativeLayout layout = new RelativeLayout(mThemedContext);
|
||||
layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
|
||||
LayoutParams.MATCH_PARENT));
|
||||
mContentRoot.addView(layout);
|
||||
// Create a layout for the user's content.
|
||||
FrameLayout contentRoot = new FrameLayout(mBridgeContext);
|
||||
contentRoot.setLayoutParams(new LayoutParams(
|
||||
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
|
||||
// Add contentRoot and menus to the layout.
|
||||
layout.addView(contentRoot);
|
||||
layout.addView(createMenuView());
|
||||
// ContentRoot is now the view we just created.
|
||||
mContentRoot = contentRoot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link LinearLayout} containing the menu list view to be embedded in a
|
||||
* {@link RelativeLayout}
|
||||
*/
|
||||
private View createMenuView() {
|
||||
DisplayMetrics metrics = mBridgeContext.getMetrics();
|
||||
OverflowMenuAdapter adapter = new OverflowMenuAdapter(mMenuBuilder, mThemedContext);
|
||||
|
||||
LinearLayout layout = new LinearLayout(mThemedContext);
|
||||
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
|
||||
measureContentWidth(adapter), LayoutParams.WRAP_CONTENT);
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
|
||||
if (mSplit) {
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
|
||||
// TODO: Find correct value instead of hardcoded 10dp.
|
||||
layoutParams.bottomMargin = getPixelValue("-10dp", metrics);
|
||||
} else {
|
||||
layoutParams.topMargin = getPixelValue("-10dp", metrics);
|
||||
}
|
||||
layout.setLayoutParams(layoutParams);
|
||||
final TypedArray a = mThemedContext.obtainStyledAttributes(null,
|
||||
R.styleable.PopupWindow, R.attr.popupMenuStyle, 0);
|
||||
layout.setBackground(a.getDrawable(R.styleable.PopupWindow_popupBackground));
|
||||
layout.setDividerDrawable(a.getDrawable(R.attr.actionBarDivider));
|
||||
a.recycle();
|
||||
layout.setOrientation(LinearLayout.VERTICAL);
|
||||
layout.setDividerPadding(getPixelValue("12dp", metrics));
|
||||
layout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
|
||||
|
||||
ListView listView = new ListView(mThemedContext, null, R.attr.dropDownListViewStyle);
|
||||
listView.setAdapter(adapter);
|
||||
layout.addView(listView);
|
||||
return layout;
|
||||
}
|
||||
|
||||
private boolean isOverflowPopupNeeded() {
|
||||
boolean needed = mCallback.isOverflowPopupNeeded();
|
||||
if (!needed) {
|
||||
return false;
|
||||
}
|
||||
// Copied from android.widget.ActionMenuPresenter.updateMenuView()
|
||||
ArrayList<MenuItemImpl> menus = MenuBuilderAccessor.getNonActionItems(mMenuBuilder);
|
||||
if (ActionBarAccessor.getActionMenuPresenter(mActionBarView).isOverflowReserved() &&
|
||||
menus != null) {
|
||||
final int count = menus.size();
|
||||
if (count == 1) {
|
||||
needed = !menus.get(0).isActionViewExpanded();
|
||||
} else {
|
||||
needed = count > 0;
|
||||
}
|
||||
}
|
||||
return needed;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FrameLayout getContentRoot() {
|
||||
return mContentRoot;
|
||||
}
|
||||
|
||||
// Copied from com.android.internal.view.menu.MenuPopHelper.measureContentWidth()
|
||||
private int measureContentWidth(ListAdapter adapter) {
|
||||
// Menus don't tend to be long, so this is more sane than it looks.
|
||||
int maxWidth = 0;
|
||||
View itemView = null;
|
||||
int itemType = 0;
|
||||
|
||||
final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
|
||||
final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
|
||||
final int count = adapter.getCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
final int positionType = adapter.getItemViewType(i);
|
||||
if (positionType != itemType) {
|
||||
itemType = positionType;
|
||||
itemView = null;
|
||||
}
|
||||
|
||||
if (mMeasureParent == null) {
|
||||
mMeasureParent = new FrameLayout(mThemedContext);
|
||||
}
|
||||
|
||||
itemView = adapter.getView(i, itemView, mMeasureParent);
|
||||
itemView.measure(widthMeasureSpec, heightMeasureSpec);
|
||||
|
||||
final int itemWidth = itemView.getMeasuredWidth();
|
||||
if (itemWidth >= mPopupMaxWidth) {
|
||||
return mPopupMaxWidth;
|
||||
} else if (itemWidth > maxWidth) {
|
||||
maxWidth = itemWidth;
|
||||
}
|
||||
}
|
||||
|
||||
return maxWidth;
|
||||
}
|
||||
|
||||
private int getPixelValue(String value, DisplayMetrics metrics) {
|
||||
TypedValue typedValue = ResourceHelper.getValue(null, value, false /*requireUnit*/);
|
||||
return (int) typedValue.getDimension(metrics);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.layoutlib.bridge.bars;
|
||||
|
||||
import com.android.internal.view.menu.MenuBuilder;
|
||||
import com.android.internal.view.menu.MenuBuilderAccessor;
|
||||
import com.android.internal.view.menu.MenuItemImpl;
|
||||
import com.android.internal.view.menu.MenuView;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Provides an adapter for Overflow menu popup. This is very similar to
|
||||
* {@code MenuPopupHelper.MenuAdapter}
|
||||
*/
|
||||
public class OverflowMenuAdapter extends BaseAdapter {
|
||||
|
||||
private final MenuBuilder mMenu;
|
||||
private int mExpandedIndex = -1;
|
||||
private final Context context;
|
||||
|
||||
public OverflowMenuAdapter(MenuBuilder menu, Context context) {
|
||||
mMenu = menu;
|
||||
findExpandedIndex();
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
ArrayList<MenuItemImpl> items = MenuBuilderAccessor.getNonActionItems(mMenu);
|
||||
if (mExpandedIndex < 0) {
|
||||
return items.size();
|
||||
}
|
||||
return items.size() - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MenuItemImpl getItem(int position) {
|
||||
ArrayList<MenuItemImpl> items = MenuBuilderAccessor.getNonActionItems(mMenu);
|
||||
if (mExpandedIndex >= 0 && position >= mExpandedIndex) {
|
||||
position++;
|
||||
}
|
||||
return items.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
// Since a menu item's ID is optional, we'll use the position as an
|
||||
// ID for the item in the AdapterView
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
if (convertView == null) {
|
||||
LayoutInflater mInflater = LayoutInflater.from(context);
|
||||
convertView = mInflater.inflate(com.android.internal.R.layout.popup_menu_item_layout,
|
||||
parent, false);
|
||||
}
|
||||
|
||||
MenuView.ItemView itemView = (MenuView.ItemView) convertView;
|
||||
itemView.initialize(getItem(position), 0);
|
||||
return convertView;
|
||||
}
|
||||
|
||||
private void findExpandedIndex() {
|
||||
final MenuItemImpl expandedItem = mMenu.getExpandedItem();
|
||||
if (expandedItem != null) {
|
||||
final ArrayList<MenuItemImpl> items = MenuBuilderAccessor.getNonActionItems(mMenu);
|
||||
final int count = items.size();
|
||||
for (int i = 0; i < count; i++) {
|
||||
final MenuItemImpl item = items.get(i);
|
||||
if (item == expandedItem) {
|
||||
mExpandedIndex = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,10 +147,11 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
|
||||
/**
|
||||
* Creates a layout scene with all the information coming from the layout bridge API.
|
||||
* <p>
|
||||
* This <b>must</b> be followed by a call to {@link RenderSessionImpl#init()}, which act as a
|
||||
* This <b>must</b> be followed by a call to {@link RenderSessionImpl#init(long)},
|
||||
* which act as a
|
||||
* call to {@link RenderSessionImpl#acquire(long)}
|
||||
*
|
||||
* @see LayoutBridge#createScene(com.android.layoutlib.api.SceneParams)
|
||||
* @see Bridge#createSession(SessionParams)
|
||||
*/
|
||||
public RenderSessionImpl(SessionParams params) {
|
||||
super(new SessionParams(params));
|
||||
@@ -218,6 +219,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
|
||||
SessionParams params = getParams();
|
||||
HardwareConfig hardwareConfig = params.getHardwareConfig();
|
||||
BridgeContext context = getContext();
|
||||
ActionBarLayout actionBar = null;
|
||||
|
||||
// the view group that receives the window background.
|
||||
ViewGroup backgroundView = null;
|
||||
@@ -317,9 +319,10 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
|
||||
// if the theme says no title/action bar, then the size will be 0
|
||||
if (mActionBarSize > 0) {
|
||||
try {
|
||||
ActionBarLayout actionBar = createActionBar(context, params);
|
||||
actionBar = createActionBar(context, params);
|
||||
backgroundLayout.addView(actionBar);
|
||||
mContentRoot = (FrameLayout) actionBar.findViewById(android.R.id.content);
|
||||
actionBar.createMenuPopup();
|
||||
mContentRoot = actionBar.getContentRoot();
|
||||
} catch (XmlPullParserException e) {
|
||||
|
||||
}
|
||||
@@ -406,7 +409,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
|
||||
* @throws IllegalStateException if the current context is different than the one owned by
|
||||
* the scene, or if {@link #acquire(long)} was not called.
|
||||
*
|
||||
* @see RenderParams#getRenderingMode()
|
||||
* @see SessionParams#getRenderingMode()
|
||||
* @see RenderSession#render(long)
|
||||
*/
|
||||
public Result render(boolean freshRender) {
|
||||
@@ -1364,7 +1367,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
|
||||
|
||||
/**
|
||||
* Visits all the children of a given ViewGroup and generates a list of {@link ViewInfo}
|
||||
* containing the bounds of all the views. It also initializes the {@link mViewInfoList} with
|
||||
* containing the bounds of all the views. It also initializes the {@link #mViewInfoList} with
|
||||
* the children of the {@code mContentRoot}.
|
||||
*
|
||||
* @param viewGroup the root View
|
||||
|
||||
Reference in New Issue
Block a user