Loading core/java/android/view/MenuInflater.java +31 −5 Original line number Diff line number Diff line Loading @@ -161,6 +161,7 @@ public class MenuInflater { } else if (tagName.equals(XML_MENU)) { // A menu start tag denotes a submenu for an item SubMenu subMenu = menuState.addSubMenuItem(); registerMenu(subMenu, attrs); // Parse the submenu into returned SubMenu parseMenu(parser, attrs, subMenu); Loading @@ -183,9 +184,9 @@ public class MenuInflater { if (!menuState.hasAddedItem()) { if (menuState.itemActionProvider != null && menuState.itemActionProvider.hasSubMenu()) { menuState.addSubMenuItem(); registerMenu(menuState.addSubMenuItem(), attrs); } else { menuState.addItem(); registerMenu(menuState.addItem(), attrs); } } } else if (tagName.equals(XML_MENU)) { Loading @@ -201,6 +202,29 @@ public class MenuInflater { } } /** * The method is a hook for layoutlib to do its magic. * Nothing is needed outside of LayoutLib. However, it should not be deleted because it * appears to do nothing. */ private void registerMenu(@SuppressWarnings("unused") MenuItem item, @SuppressWarnings("unused") AttributeSet set) { } /** * The method is a hook for layoutlib to do its magic. * Nothing is needed outside of LayoutLib. However, it should not be deleted because it * appears to do nothing. */ private void registerMenu(@SuppressWarnings("unused") SubMenu subMenu, @SuppressWarnings("unused") AttributeSet set) { } // Needed by layoutlib. /*package*/ Context getContext() { return mContext; } private static class InflatedOnMenuItemClickListener implements MenuItem.OnMenuItemClickListener { private static final Class<?>[] PARAM_TYPES = new Class[] { MenuItem.class }; Loading Loading @@ -446,9 +470,11 @@ public class MenuInflater { } } public void addItem() { public MenuItem addItem() { itemAdded = true; setItem(menu.add(groupId, itemId, itemCategoryOrder, itemTitle)); MenuItem item = menu.add(groupId, itemId, itemCategoryOrder, itemTitle); setItem(item); return item; } public SubMenu addSubMenuItem() { Loading core/java/com/android/internal/view/menu/MenuBuilder.java +10 −3 Original line number Diff line number Diff line Loading @@ -392,8 +392,8 @@ public class MenuBuilder implements Menu { private MenuItem addInternal(int group, int id, int categoryOrder, CharSequence title) { final int ordering = getOrdering(categoryOrder); final MenuItemImpl item = new MenuItemImpl(this, group, id, categoryOrder, ordering, title, mDefaultShowAsAction); final MenuItemImpl item = createNewMenuItem(group, id, categoryOrder, ordering, title, mDefaultShowAsAction); if (mCurrentMenuInfo != null) { // Pass along the current menu info Loading @@ -406,6 +406,13 @@ public class MenuBuilder implements Menu { return item; } // Layoutlib overrides this method to return its custom implementation of MenuItemImpl private MenuItemImpl createNewMenuItem(int group, int id, int categoryOrder, int ordering, CharSequence title, int defaultShowAsAction) { return new MenuItemImpl(this, group, id, categoryOrder, ordering, title, defaultShowAsAction); } public MenuItem add(CharSequence title) { return addInternal(0, 0, 0, title); } Loading tools/layoutlib/bridge/src/android/view/BridgeInflater.java +53 −41 Original line number Diff line number Diff line Loading @@ -32,10 +32,6 @@ import org.xmlpull.v1.XmlPullParser; import android.content.Context; import android.util.AttributeSet; import android.view.InflateException; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import java.io.File; Loading Loading @@ -154,6 +150,9 @@ public final class BridgeInflater extends LayoutInflater { @Override public View inflate(int resource, ViewGroup root) { Context context = getContext(); if (context instanceof ContextThemeWrapper) { context = ((ContextThemeWrapper) context).getBaseContext(); } if (context instanceof BridgeContext) { BridgeContext bridgeContext = (BridgeContext)context; Loading Loading @@ -216,10 +215,40 @@ public final class BridgeInflater extends LayoutInflater { } private void setupViewInContext(View view, AttributeSet attrs) { if (getContext() instanceof BridgeContext) { BridgeContext bc = (BridgeContext) getContext(); if (attrs instanceof BridgeXmlBlockParser) { BridgeXmlBlockParser parser = (BridgeXmlBlockParser) attrs; Context context = getContext(); if (context instanceof ContextThemeWrapper) { context = ((ContextThemeWrapper) context).getBaseContext(); } if (context instanceof BridgeContext) { BridgeContext bc = (BridgeContext) context; // get the view key Object viewKey = getViewKeyFromParser(attrs, bc, mResourceReference, mIsInMerge); if (viewKey != null) { bc.addViewKey(view, viewKey); } } } public void setIsInMerge(boolean isInMerge) { mIsInMerge = isInMerge; } public void setResourceReference(ResourceReference reference) { mResourceReference = reference; } @Override public LayoutInflater cloneInContext(Context newContext) { return new BridgeInflater(this, newContext); } /*package*/ static Object getViewKeyFromParser(AttributeSet attrs, BridgeContext bc, ResourceReference resourceReference, boolean isInMerge) { if (!(attrs instanceof BridgeXmlBlockParser)) { return null; } BridgeXmlBlockParser parser = ((BridgeXmlBlockParser) attrs); // get the view key Object viewKey = parser.getViewCookie(); Loading @@ -230,43 +259,26 @@ public final class BridgeInflater extends LayoutInflater { // test whether we are in an included file or in a adapter binding view. BridgeXmlBlockParser previousParser = bc.getPreviousParser(); if (previousParser != null) { // looks like we inside an embedded layout. // looks like we are inside an embedded layout. // only apply the cookie of the calling node (<include>) if we are at the // top level of the embedded layout. If there is a merge tag, then // skip it and look for the 2nd level int testDepth = mIsInMerge ? 2 : 1; int testDepth = isInMerge ? 2 : 1; if (currentDepth == testDepth) { viewKey = previousParser.getViewCookie(); // if we are in a merge, wrap the cookie in a MergeCookie. if (viewKey != null && mIsInMerge) { if (viewKey != null && isInMerge) { viewKey = new MergeCookie(viewKey); } } } else if (mResourceReference != null && currentDepth == 1) { } else if (resourceReference != null && currentDepth == 1) { // else if there's a resource reference, this means we are in an adapter // binding case. Set the resource ref as the view cookie only for the top // level view. viewKey = mResourceReference; } } if (viewKey != null) { bc.addViewKey(view, viewKey); } } viewKey = resourceReference; } } public void setIsInMerge(boolean isInMerge) { mIsInMerge = isInMerge; } public void setResourceReference(ResourceReference reference) { mResourceReference = reference; } @Override public LayoutInflater cloneInContext(Context newContext) { return new BridgeInflater(this, newContext); return viewKey; } } tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java 0 → 100644 +75 −0 Original line number Diff line number Diff line /* * 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 android.view; import android.content.Context; import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.ViewInfo; import com.android.internal.view.menu.BridgeMenuItemImpl; import com.android.internal.view.menu.MenuView; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.BridgeContext; import com.android.layoutlib.bridge.android.BridgeXmlBlockParser; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; import android.util.AttributeSet; /** * Delegate used to provide new implementation of a select few methods of {@link MenuInflater} * <p/> * Through the layoutlib_create tool, the original methods of MenuInflater have been * replaced by calls to methods of the same name in this delegate class. * <p/> * The main purpose of the class is to get the view key from the menu xml parser and add it to * the menu item. The view key is used by the IDE to match the individual view elements to the * corresponding xml tag in the menu/layout file. * <p/> * For Menus, the views may be reused and the {@link MenuItem} is a better object to hold the * view key than the {@link MenuView.ItemView}. At the time of computation of the rest of {@link * ViewInfo}, we check the corresponding view key in the menu item for the view and add it */ public class MenuInflater_Delegate { @LayoutlibDelegate /*package*/ static void registerMenu(MenuInflater thisInflater, MenuItem menuItem, AttributeSet attrs) { if (menuItem instanceof BridgeMenuItemImpl) { Context context = thisInflater.getContext(); if (context instanceof ContextThemeWrapper) { context = ((ContextThemeWrapper) context).getBaseContext(); } if (context instanceof BridgeContext) { Object viewKey = BridgeInflater.getViewKeyFromParser( attrs, ((BridgeContext) context), null, false); ((BridgeMenuItemImpl) menuItem).setViewCookie(viewKey); return; } } // This means that Bridge did not take over the instantiation of some object properly. // This is most likely a bug in the LayoutLib code. Bridge.getLog().warning(LayoutLog.TAG_BROKEN, "Action Bar Menu rendering may be incorrect.", null); } @LayoutlibDelegate /*package*/ static void registerMenu(MenuInflater thisInflater, SubMenu subMenu, AttributeSet parser) { registerMenu(thisInflater, subMenu.getItem(), parser); } } tools/layoutlib/bridge/src/com/android/internal/view/menu/BridgeMenuItemImpl.java 0 → 100644 +47 −0 Original line number Diff line number Diff line /* * 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.view.menu; /** * An extension of the {@link MenuItemImpl} to store the view cookie also. */ public class BridgeMenuItemImpl extends MenuItemImpl { /** * An object returned by the IDE that helps mapping each View to the corresponding XML tag in * the layout. For Menus, we store this cookie here and attach it to the corresponding view * at the time of rendering. */ private Object viewCookie; /** * Instantiates this menu item. */ BridgeMenuItemImpl(MenuBuilder menu, int group, int id, int categoryOrder, int ordering, CharSequence title, int showAsAction) { super(menu, group, id, categoryOrder, ordering, title, showAsAction); } public Object getViewCookie() { return viewCookie; } public void setViewCookie(Object viewCookie) { this.viewCookie = viewCookie; } } Loading
core/java/android/view/MenuInflater.java +31 −5 Original line number Diff line number Diff line Loading @@ -161,6 +161,7 @@ public class MenuInflater { } else if (tagName.equals(XML_MENU)) { // A menu start tag denotes a submenu for an item SubMenu subMenu = menuState.addSubMenuItem(); registerMenu(subMenu, attrs); // Parse the submenu into returned SubMenu parseMenu(parser, attrs, subMenu); Loading @@ -183,9 +184,9 @@ public class MenuInflater { if (!menuState.hasAddedItem()) { if (menuState.itemActionProvider != null && menuState.itemActionProvider.hasSubMenu()) { menuState.addSubMenuItem(); registerMenu(menuState.addSubMenuItem(), attrs); } else { menuState.addItem(); registerMenu(menuState.addItem(), attrs); } } } else if (tagName.equals(XML_MENU)) { Loading @@ -201,6 +202,29 @@ public class MenuInflater { } } /** * The method is a hook for layoutlib to do its magic. * Nothing is needed outside of LayoutLib. However, it should not be deleted because it * appears to do nothing. */ private void registerMenu(@SuppressWarnings("unused") MenuItem item, @SuppressWarnings("unused") AttributeSet set) { } /** * The method is a hook for layoutlib to do its magic. * Nothing is needed outside of LayoutLib. However, it should not be deleted because it * appears to do nothing. */ private void registerMenu(@SuppressWarnings("unused") SubMenu subMenu, @SuppressWarnings("unused") AttributeSet set) { } // Needed by layoutlib. /*package*/ Context getContext() { return mContext; } private static class InflatedOnMenuItemClickListener implements MenuItem.OnMenuItemClickListener { private static final Class<?>[] PARAM_TYPES = new Class[] { MenuItem.class }; Loading Loading @@ -446,9 +470,11 @@ public class MenuInflater { } } public void addItem() { public MenuItem addItem() { itemAdded = true; setItem(menu.add(groupId, itemId, itemCategoryOrder, itemTitle)); MenuItem item = menu.add(groupId, itemId, itemCategoryOrder, itemTitle); setItem(item); return item; } public SubMenu addSubMenuItem() { Loading
core/java/com/android/internal/view/menu/MenuBuilder.java +10 −3 Original line number Diff line number Diff line Loading @@ -392,8 +392,8 @@ public class MenuBuilder implements Menu { private MenuItem addInternal(int group, int id, int categoryOrder, CharSequence title) { final int ordering = getOrdering(categoryOrder); final MenuItemImpl item = new MenuItemImpl(this, group, id, categoryOrder, ordering, title, mDefaultShowAsAction); final MenuItemImpl item = createNewMenuItem(group, id, categoryOrder, ordering, title, mDefaultShowAsAction); if (mCurrentMenuInfo != null) { // Pass along the current menu info Loading @@ -406,6 +406,13 @@ public class MenuBuilder implements Menu { return item; } // Layoutlib overrides this method to return its custom implementation of MenuItemImpl private MenuItemImpl createNewMenuItem(int group, int id, int categoryOrder, int ordering, CharSequence title, int defaultShowAsAction) { return new MenuItemImpl(this, group, id, categoryOrder, ordering, title, defaultShowAsAction); } public MenuItem add(CharSequence title) { return addInternal(0, 0, 0, title); } Loading
tools/layoutlib/bridge/src/android/view/BridgeInflater.java +53 −41 Original line number Diff line number Diff line Loading @@ -32,10 +32,6 @@ import org.xmlpull.v1.XmlPullParser; import android.content.Context; import android.util.AttributeSet; import android.view.InflateException; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import java.io.File; Loading Loading @@ -154,6 +150,9 @@ public final class BridgeInflater extends LayoutInflater { @Override public View inflate(int resource, ViewGroup root) { Context context = getContext(); if (context instanceof ContextThemeWrapper) { context = ((ContextThemeWrapper) context).getBaseContext(); } if (context instanceof BridgeContext) { BridgeContext bridgeContext = (BridgeContext)context; Loading Loading @@ -216,10 +215,40 @@ public final class BridgeInflater extends LayoutInflater { } private void setupViewInContext(View view, AttributeSet attrs) { if (getContext() instanceof BridgeContext) { BridgeContext bc = (BridgeContext) getContext(); if (attrs instanceof BridgeXmlBlockParser) { BridgeXmlBlockParser parser = (BridgeXmlBlockParser) attrs; Context context = getContext(); if (context instanceof ContextThemeWrapper) { context = ((ContextThemeWrapper) context).getBaseContext(); } if (context instanceof BridgeContext) { BridgeContext bc = (BridgeContext) context; // get the view key Object viewKey = getViewKeyFromParser(attrs, bc, mResourceReference, mIsInMerge); if (viewKey != null) { bc.addViewKey(view, viewKey); } } } public void setIsInMerge(boolean isInMerge) { mIsInMerge = isInMerge; } public void setResourceReference(ResourceReference reference) { mResourceReference = reference; } @Override public LayoutInflater cloneInContext(Context newContext) { return new BridgeInflater(this, newContext); } /*package*/ static Object getViewKeyFromParser(AttributeSet attrs, BridgeContext bc, ResourceReference resourceReference, boolean isInMerge) { if (!(attrs instanceof BridgeXmlBlockParser)) { return null; } BridgeXmlBlockParser parser = ((BridgeXmlBlockParser) attrs); // get the view key Object viewKey = parser.getViewCookie(); Loading @@ -230,43 +259,26 @@ public final class BridgeInflater extends LayoutInflater { // test whether we are in an included file or in a adapter binding view. BridgeXmlBlockParser previousParser = bc.getPreviousParser(); if (previousParser != null) { // looks like we inside an embedded layout. // looks like we are inside an embedded layout. // only apply the cookie of the calling node (<include>) if we are at the // top level of the embedded layout. If there is a merge tag, then // skip it and look for the 2nd level int testDepth = mIsInMerge ? 2 : 1; int testDepth = isInMerge ? 2 : 1; if (currentDepth == testDepth) { viewKey = previousParser.getViewCookie(); // if we are in a merge, wrap the cookie in a MergeCookie. if (viewKey != null && mIsInMerge) { if (viewKey != null && isInMerge) { viewKey = new MergeCookie(viewKey); } } } else if (mResourceReference != null && currentDepth == 1) { } else if (resourceReference != null && currentDepth == 1) { // else if there's a resource reference, this means we are in an adapter // binding case. Set the resource ref as the view cookie only for the top // level view. viewKey = mResourceReference; } } if (viewKey != null) { bc.addViewKey(view, viewKey); } } viewKey = resourceReference; } } public void setIsInMerge(boolean isInMerge) { mIsInMerge = isInMerge; } public void setResourceReference(ResourceReference reference) { mResourceReference = reference; } @Override public LayoutInflater cloneInContext(Context newContext) { return new BridgeInflater(this, newContext); return viewKey; } }
tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java 0 → 100644 +75 −0 Original line number Diff line number Diff line /* * 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 android.view; import android.content.Context; import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.ViewInfo; import com.android.internal.view.menu.BridgeMenuItemImpl; import com.android.internal.view.menu.MenuView; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.BridgeContext; import com.android.layoutlib.bridge.android.BridgeXmlBlockParser; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; import android.util.AttributeSet; /** * Delegate used to provide new implementation of a select few methods of {@link MenuInflater} * <p/> * Through the layoutlib_create tool, the original methods of MenuInflater have been * replaced by calls to methods of the same name in this delegate class. * <p/> * The main purpose of the class is to get the view key from the menu xml parser and add it to * the menu item. The view key is used by the IDE to match the individual view elements to the * corresponding xml tag in the menu/layout file. * <p/> * For Menus, the views may be reused and the {@link MenuItem} is a better object to hold the * view key than the {@link MenuView.ItemView}. At the time of computation of the rest of {@link * ViewInfo}, we check the corresponding view key in the menu item for the view and add it */ public class MenuInflater_Delegate { @LayoutlibDelegate /*package*/ static void registerMenu(MenuInflater thisInflater, MenuItem menuItem, AttributeSet attrs) { if (menuItem instanceof BridgeMenuItemImpl) { Context context = thisInflater.getContext(); if (context instanceof ContextThemeWrapper) { context = ((ContextThemeWrapper) context).getBaseContext(); } if (context instanceof BridgeContext) { Object viewKey = BridgeInflater.getViewKeyFromParser( attrs, ((BridgeContext) context), null, false); ((BridgeMenuItemImpl) menuItem).setViewCookie(viewKey); return; } } // This means that Bridge did not take over the instantiation of some object properly. // This is most likely a bug in the LayoutLib code. Bridge.getLog().warning(LayoutLog.TAG_BROKEN, "Action Bar Menu rendering may be incorrect.", null); } @LayoutlibDelegate /*package*/ static void registerMenu(MenuInflater thisInflater, SubMenu subMenu, AttributeSet parser) { registerMenu(thisInflater, subMenu.getItem(), parser); } }
tools/layoutlib/bridge/src/com/android/internal/view/menu/BridgeMenuItemImpl.java 0 → 100644 +47 −0 Original line number Diff line number Diff line /* * 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.view.menu; /** * An extension of the {@link MenuItemImpl} to store the view cookie also. */ public class BridgeMenuItemImpl extends MenuItemImpl { /** * An object returned by the IDE that helps mapping each View to the corresponding XML tag in * the layout. For Menus, we store this cookie here and attach it to the corresponding view * at the time of rendering. */ private Object viewCookie; /** * Instantiates this menu item. */ BridgeMenuItemImpl(MenuBuilder menu, int group, int id, int categoryOrder, int ordering, CharSequence title, int showAsAction) { super(menu, group, id, categoryOrder, ordering, title, showAsAction); } public Object getViewCookie() { return viewCookie; } public void setViewCookie(Object viewCookie) { this.viewCookie = viewCookie; } }