18262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns/* 28262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * Copyright (C) 2013 The Android Open Source Project 38262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * 48262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * Licensed under the Apache License, Version 2.0 (the "License"); 58262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * you may not use this file except in compliance with the License. 68262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * You may obtain a copy of the License at 78262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * 88262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * http://www.apache.org/licenses/LICENSE-2.0 98262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * 108262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * Unless required by applicable law or agreed to in writing, software 118262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * distributed under the License is distributed on an "AS IS" BASIS, 128262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * See the License for the specific language governing permissions and 148262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * limitations under the License. 158262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns */ 168262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.appcompat.view; 188262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 19ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP; 20592df2e7552ba6902c9750ab8453850fc9e30334Chris Banes 218262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport android.app.Activity; 228262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport android.content.Context; 23eeb589a57c069e1c1313e74de5876eceb69812a3Yigit Boyarimport android.content.ContextWrapper; 243a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikovimport android.content.res.ColorStateList; 258262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport android.content.res.TypedArray; 268262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport android.content.res.XmlResourceParser; 273a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikovimport android.graphics.PorterDuff; 288262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport android.util.AttributeSet; 298262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport android.util.Log; 308262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport android.util.Xml; 318262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport android.view.InflateException; 3209231da6d922e91d30d06876521106f13230a791Peeyush Agarwalimport android.view.KeyEvent; 3330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.Menu; 3430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.MenuInflater; 3530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.MenuItem; 3630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.SubMenu; 378262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport android.view.View; 388262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 393de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikasimport androidx.annotation.LayoutRes; 403de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikasimport androidx.annotation.RestrictTo; 413de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikasimport androidx.appcompat.R; 423de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikasimport androidx.appcompat.view.menu.MenuItemImpl; 433de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikasimport androidx.appcompat.view.menu.MenuItemWrapperICS; 443de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikasimport androidx.appcompat.widget.DrawableUtils; 453de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikasimport androidx.core.internal.view.SupportMenu; 463de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikasimport androidx.core.view.ActionProvider; 473de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikasimport androidx.core.view.MenuItemCompat; 483de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikas 498e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikasimport org.xmlpull.v1.XmlPullParser; 508e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikasimport org.xmlpull.v1.XmlPullParserException; 518e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas 528262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport java.io.IOException; 538262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport java.lang.reflect.Constructor; 548262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport java.lang.reflect.Method; 558262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 568262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns/** 578262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * This class is used to instantiate menu XML files into Menu objects. 588262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * <p> 598262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * For performance reasons, menu inflation relies heavily on pre-processing of 608262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * XML files that is done at build time. Therefore, it is not currently possible 61e0f27d39b0a4f0ef30ef6446e7b675279961cc94Chris Banes * to use SupportMenuInflater with an XmlPullParser over a plain XML file at runtime; 628262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * it only works with an XmlPullParser returned from a compiled resource (R. 638262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * <em>something</em> file.) 6489208232f3b5d1451408d787872504a190bc7ee0Chris Banes * 6589208232f3b5d1451408d787872504a190bc7ee0Chris Banes * @hide 668262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns */ 678e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas@RestrictTo(LIBRARY_GROUP) 6830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellpublic class SupportMenuInflater extends MenuInflater { 692c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas static final String LOG_TAG = "SupportMenuInflater"; 708262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 718262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns /** Menu tag name in XML. */ 728262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private static final String XML_MENU = "menu"; 738262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 748262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns /** Group tag name in XML. */ 758262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private static final String XML_GROUP = "group"; 768262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 778262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns /** Item tag name in XML. */ 788262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private static final String XML_ITEM = "item"; 798262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 802c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas static final int NO_ID = 0; 818262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 822c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas static final Class<?>[] ACTION_VIEW_CONSTRUCTOR_SIGNATURE = new Class[] {Context.class}; 838262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 842c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas static final Class<?>[] ACTION_PROVIDER_CONSTRUCTOR_SIGNATURE = 858262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns ACTION_VIEW_CONSTRUCTOR_SIGNATURE; 868262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 872c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas final Object[] mActionViewConstructorArguments; 888262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 892c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas final Object[] mActionProviderConstructorArguments; 908262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 912c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas Context mContext; 928262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private Object mRealOwner; 938262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 948262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns /** 958262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * Constructs a menu inflater. 968262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * 978262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * @see Activity#getMenuInflater() 988262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns */ 99e0f27d39b0a4f0ef30ef6446e7b675279961cc94Chris Banes public SupportMenuInflater(Context context) { 10030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell super(context); 1018262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns mContext = context; 1028262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns mActionViewConstructorArguments = new Object[] {context}; 1038262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns mActionProviderConstructorArguments = mActionViewConstructorArguments; 1048262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 1058262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 1068262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns /** 1078262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * Inflate a menu hierarchy from the specified XML resource. Throws 1088262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * {@link InflateException} if there is an error. 1098262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * 1108262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * @param menuRes Resource ID for an XML layout resource to load (e.g., 1118262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * <code>R.menu.main_activity</code>) 1128262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * @param menu The Menu to inflate into. The items and submenus will be 1138262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * added to this Menu. 1148262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns */ 115e0f27d39b0a4f0ef30ef6446e7b675279961cc94Chris Banes @Override 11650b45b25e10ddbfd726b91910e00bce6a1c63904Aurimas Liutikas public void inflate(@LayoutRes int menuRes, Menu menu) { 11703527a1c5ca870353671fd8b97a08a989fe62012Chris Banes // If we're not dealing with a SupportMenu instance, let super handle 11803527a1c5ca870353671fd8b97a08a989fe62012Chris Banes if (!(menu instanceof SupportMenu)) { 11903527a1c5ca870353671fd8b97a08a989fe62012Chris Banes super.inflate(menuRes, menu); 12003527a1c5ca870353671fd8b97a08a989fe62012Chris Banes return; 12103527a1c5ca870353671fd8b97a08a989fe62012Chris Banes } 12203527a1c5ca870353671fd8b97a08a989fe62012Chris Banes 1238262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns XmlResourceParser parser = null; 1248262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns try { 1258262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns parser = mContext.getResources().getLayout(menuRes); 1268262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns AttributeSet attrs = Xml.asAttributeSet(parser); 1278262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 1288262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns parseMenu(parser, attrs, menu); 1298262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } catch (XmlPullParserException e) { 1308262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns throw new InflateException("Error inflating menu XML", e); 1318262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } catch (IOException e) { 1328262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns throw new InflateException("Error inflating menu XML", e); 1338262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } finally { 1348262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns if (parser != null) parser.close(); 1358262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 1368262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 1378262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 1388262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns /** 1398262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * Called internally to fill the given menu. If a sub menu is seen, it will 1408262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * call this recursively. 1418262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns */ 1428262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private void parseMenu(XmlPullParser parser, AttributeSet attrs, Menu menu) 1438262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns throws XmlPullParserException, IOException { 1448262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns MenuState menuState = new MenuState(menu); 1458262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 1468262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns int eventType = parser.getEventType(); 1478262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns String tagName; 1488262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns boolean lookingForEndOfUnknownTag = false; 1498262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns String unknownTagName = null; 1508262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 1518262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns // This loop will skip to the menu start tag 1528262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns do { 1538262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns if (eventType == XmlPullParser.START_TAG) { 1548262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns tagName = parser.getName(); 1558262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns if (tagName.equals(XML_MENU)) { 1568262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns // Go to next tag 1578262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns eventType = parser.next(); 1588262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns break; 1598262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 1608262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 1618262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns throw new RuntimeException("Expecting menu, got " + tagName); 1628262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 1638262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns eventType = parser.next(); 1648262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } while (eventType != XmlPullParser.END_DOCUMENT); 1658262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 1668262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns boolean reachedEndOfMenu = false; 1678262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns while (!reachedEndOfMenu) { 1688262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns switch (eventType) { 1698262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns case XmlPullParser.START_TAG: 1708262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns if (lookingForEndOfUnknownTag) { 1718262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns break; 1728262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 1738262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 1748262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns tagName = parser.getName(); 1758262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns if (tagName.equals(XML_GROUP)) { 1768262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns menuState.readGroup(attrs); 1778262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } else if (tagName.equals(XML_ITEM)) { 1788262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns menuState.readItem(attrs); 1798262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } else if (tagName.equals(XML_MENU)) { 1808262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns // A menu start tag denotes a submenu for an item 1818262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns SubMenu subMenu = menuState.addSubMenuItem(); 1828262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 1838262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns // Parse the submenu into returned SubMenu 1848262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns parseMenu(parser, attrs, subMenu); 1858262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } else { 1868262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns lookingForEndOfUnknownTag = true; 1878262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns unknownTagName = tagName; 1888262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 1898262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns break; 1908262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 1918262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns case XmlPullParser.END_TAG: 1928262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns tagName = parser.getName(); 1938262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns if (lookingForEndOfUnknownTag && tagName.equals(unknownTagName)) { 1948262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns lookingForEndOfUnknownTag = false; 1958262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns unknownTagName = null; 1968262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } else if (tagName.equals(XML_GROUP)) { 1978262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns menuState.resetGroup(); 1988262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } else if (tagName.equals(XML_ITEM)) { 1998262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns // Add the item if it hasn't been added (if the item was 2008262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns // a submenu, it would have been added already) 2018262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns if (!menuState.hasAddedItem()) { 2028262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns if (menuState.itemActionProvider != null && 2038262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns menuState.itemActionProvider.hasSubMenu()) { 2048262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns menuState.addSubMenuItem(); 2058262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } else { 2068262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns menuState.addItem(); 2078262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 2088262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 2098262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } else if (tagName.equals(XML_MENU)) { 2108262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns reachedEndOfMenu = true; 2118262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 2128262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns break; 2138262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 2148262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns case XmlPullParser.END_DOCUMENT: 2158262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns throw new RuntimeException("Unexpected end of document"); 2168262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 2178262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 2188262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns eventType = parser.next(); 2198262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 2208262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 2218262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 2222c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas Object getRealOwner() { 223eeb589a57c069e1c1313e74de5876eceb69812a3Yigit Boyar if (mRealOwner == null) { 224eeb589a57c069e1c1313e74de5876eceb69812a3Yigit Boyar mRealOwner = findRealOwner(mContext); 225eeb589a57c069e1c1313e74de5876eceb69812a3Yigit Boyar } 226eeb589a57c069e1c1313e74de5876eceb69812a3Yigit Boyar return mRealOwner; 227eeb589a57c069e1c1313e74de5876eceb69812a3Yigit Boyar } 228eeb589a57c069e1c1313e74de5876eceb69812a3Yigit Boyar 229eeb589a57c069e1c1313e74de5876eceb69812a3Yigit Boyar private Object findRealOwner(Object owner) { 230eeb589a57c069e1c1313e74de5876eceb69812a3Yigit Boyar if (owner instanceof Activity) { 231eeb589a57c069e1c1313e74de5876eceb69812a3Yigit Boyar return owner; 232eeb589a57c069e1c1313e74de5876eceb69812a3Yigit Boyar } 233eeb589a57c069e1c1313e74de5876eceb69812a3Yigit Boyar if (owner instanceof ContextWrapper) { 234eeb589a57c069e1c1313e74de5876eceb69812a3Yigit Boyar return findRealOwner(((ContextWrapper) owner).getBaseContext()); 235eeb589a57c069e1c1313e74de5876eceb69812a3Yigit Boyar } 236eeb589a57c069e1c1313e74de5876eceb69812a3Yigit Boyar return owner; 237eeb589a57c069e1c1313e74de5876eceb69812a3Yigit Boyar } 238eeb589a57c069e1c1313e74de5876eceb69812a3Yigit Boyar 2398262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private static class InflatedOnMenuItemClickListener 2408262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns implements MenuItem.OnMenuItemClickListener { 2418262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private static final Class<?>[] PARAM_TYPES = new Class[] { MenuItem.class }; 2428262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 2438262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private Object mRealOwner; 2448262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private Method mMethod; 2458262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 2468262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns public InflatedOnMenuItemClickListener(Object realOwner, String methodName) { 2478262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns mRealOwner = realOwner; 2488262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns Class<?> c = realOwner.getClass(); 2498262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns try { 2508262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns mMethod = c.getMethod(methodName, PARAM_TYPES); 2518262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } catch (Exception e) { 2528262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns InflateException ex = new InflateException( 2538262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns "Couldn't resolve menu item onClick handler " + methodName + 2548262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns " in class " + c.getName()); 2558262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns ex.initCause(e); 2568262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns throw ex; 2578262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 2588262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 2598262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 260e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas @Override 2618262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns public boolean onMenuItemClick(MenuItem item) { 2628262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns try { 2638262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns if (mMethod.getReturnType() == Boolean.TYPE) { 2648262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns return (Boolean) mMethod.invoke(mRealOwner, item); 2658262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } else { 2668262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns mMethod.invoke(mRealOwner, item); 2678262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns return true; 2688262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 2698262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } catch (Exception e) { 2708262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns throw new RuntimeException(e); 2718262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 2728262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 2738262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 2748262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 2758262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns /** 2768262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * State for the current menu. 2778262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * <p> 2788262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * Groups can not be nested unless there is another menu (which will have 2798262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * its state class). 2808262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns */ 2818262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private class MenuState { 2828262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private Menu menu; 2838262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 2848262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns /* 2858262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * Group state is set on items as they are added, allowing an item to 2868262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * override its group state. (As opposed to set on items at the group end tag.) 2878262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns */ 2888262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private int groupId; 2898262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private int groupCategory; 2908262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private int groupOrder; 2918262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private int groupCheckable; 2928262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private boolean groupVisible; 2938262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private boolean groupEnabled; 2948262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 2958262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private boolean itemAdded; 2968262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private int itemId; 2978262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private int itemCategoryOrder; 2988262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private CharSequence itemTitle; 2998262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private CharSequence itemTitleCondensed; 3008262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private int itemIconResId; 3018262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private char itemAlphabeticShortcut; 30209231da6d922e91d30d06876521106f13230a791Peeyush Agarwal private int itemAlphabeticModifiers; 3038262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private char itemNumericShortcut; 30409231da6d922e91d30d06876521106f13230a791Peeyush Agarwal private int itemNumericModifiers; 3058262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns /** 3068262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * Sync to attrs.xml enum: 3078262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * - 0: none 3088262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * - 1: all 3098262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * - 2: exclusive 3108262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns */ 3118262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private int itemCheckable; 3128262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private boolean itemChecked; 3138262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private boolean itemVisible; 3148262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private boolean itemEnabled; 3158262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 3168262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns /** 3178262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * Sync to attrs.xml enum, values in MenuItem: 3188262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * - 0: never 3198262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * - 1: ifRoom 3208262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * - 2: always 3218262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * - -1: Safe sentinel for "no value". 3228262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns */ 3238262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private int itemShowAsAction; 3248262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 3258262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private int itemActionViewLayout; 3268262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private String itemActionViewClassName; 3278262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private String itemActionProviderClassName; 3288262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 3298262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private String itemListenerMethodName; 3308262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 3312c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas ActionProvider itemActionProvider; 3328262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 333fd3c4560bf2348f6a06272a9f02105c9e1bf927eVladislav Kaznacheev private CharSequence itemContentDescription; 334fd3c4560bf2348f6a06272a9f02105c9e1bf927eVladislav Kaznacheev private CharSequence itemTooltipText; 335fd3c4560bf2348f6a06272a9f02105c9e1bf927eVladislav Kaznacheev 3363a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov private ColorStateList itemIconTintList = null; 3373a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov private PorterDuff.Mode itemIconTintMode = null; 3383a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov 3398262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private static final int defaultGroupId = NO_ID; 3408262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private static final int defaultItemId = NO_ID; 3418262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private static final int defaultItemCategory = 0; 3428262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private static final int defaultItemOrder = 0; 3438262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private static final int defaultItemCheckable = 0; 3448262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private static final boolean defaultItemChecked = false; 3458262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private static final boolean defaultItemVisible = true; 3468262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private static final boolean defaultItemEnabled = true; 3478262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 3488262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns public MenuState(final Menu menu) { 3498262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns this.menu = menu; 3508262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 3518262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns resetGroup(); 3528262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 3538262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 3548262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns public void resetGroup() { 3558262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns groupId = defaultGroupId; 3568262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns groupCategory = defaultItemCategory; 3578262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns groupOrder = defaultItemOrder; 3588262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns groupCheckable = defaultItemCheckable; 3598262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns groupVisible = defaultItemVisible; 3608262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns groupEnabled = defaultItemEnabled; 3618262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 3628262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 3638262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns /** 3648262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * Called when the parser is pointing to a group tag. 3658262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns */ 3668262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns public void readGroup(AttributeSet attrs) { 3678262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.MenuGroup); 3688262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 3698262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns groupId = a.getResourceId(R.styleable.MenuGroup_android_id, defaultGroupId); 3708262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns groupCategory = a.getInt( 3718262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns R.styleable.MenuGroup_android_menuCategory, defaultItemCategory); 3728262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns groupOrder = a.getInt(R.styleable.MenuGroup_android_orderInCategory, defaultItemOrder); 3738262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns groupCheckable = a.getInt( 3748262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns R.styleable.MenuGroup_android_checkableBehavior, defaultItemCheckable); 3758262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns groupVisible = a.getBoolean(R.styleable.MenuGroup_android_visible, defaultItemVisible); 3768262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns groupEnabled = a.getBoolean(R.styleable.MenuGroup_android_enabled, defaultItemEnabled); 3778262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 3788262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns a.recycle(); 3798262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 3808262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 3818262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns /** 3828262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * Called when the parser is pointing to an item tag. 3838262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns */ 3848262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns public void readItem(AttributeSet attrs) { 3858262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.MenuItem); 3868262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 3878262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns // Inherit attributes from the group as default value 3888262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns itemId = a.getResourceId(R.styleable.MenuItem_android_id, defaultItemId); 3898262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns final int category = a.getInt(R.styleable.MenuItem_android_menuCategory, groupCategory); 3908262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns final int order = a.getInt(R.styleable.MenuItem_android_orderInCategory, groupOrder); 39130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell itemCategoryOrder = (category & SupportMenu.CATEGORY_MASK) | 39230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell (order & SupportMenu.USER_MASK); 3938262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns itemTitle = a.getText(R.styleable.MenuItem_android_title); 3948262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns itemTitleCondensed = a.getText(R.styleable.MenuItem_android_titleCondensed); 3958262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns itemIconResId = a.getResourceId(R.styleable.MenuItem_android_icon, 0); 3968262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns itemAlphabeticShortcut = 3978262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns getShortcut(a.getString(R.styleable.MenuItem_android_alphabeticShortcut)); 39809231da6d922e91d30d06876521106f13230a791Peeyush Agarwal itemAlphabeticModifiers = 39909231da6d922e91d30d06876521106f13230a791Peeyush Agarwal a.getInt(R.styleable.MenuItem_alphabeticModifiers, KeyEvent.META_CTRL_ON); 4008262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns itemNumericShortcut = 4018262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns getShortcut(a.getString(R.styleable.MenuItem_android_numericShortcut)); 40209231da6d922e91d30d06876521106f13230a791Peeyush Agarwal itemNumericModifiers = 40309231da6d922e91d30d06876521106f13230a791Peeyush Agarwal a.getInt(R.styleable.MenuItem_numericModifiers, KeyEvent.META_CTRL_ON); 4048262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns if (a.hasValue(R.styleable.MenuItem_android_checkable)) { 4058262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns // Item has attribute checkable, use it 4068262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns itemCheckable = a.getBoolean(R.styleable.MenuItem_android_checkable, false) ? 1 : 0; 4078262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } else { 4088262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns // Item does not have attribute, use the group's (group can have one more state 4098262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns // for checkable that represents the exclusive checkable) 4108262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns itemCheckable = groupCheckable; 4118262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 4128262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns itemChecked = a.getBoolean(R.styleable.MenuItem_android_checked, defaultItemChecked); 4138262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns itemVisible = a.getBoolean(R.styleable.MenuItem_android_visible, groupVisible); 4148262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns itemEnabled = a.getBoolean(R.styleable.MenuItem_android_enabled, groupEnabled); 4158262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns itemShowAsAction = a.getInt(R.styleable.MenuItem_showAsAction, -1); 4168262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns itemListenerMethodName = a.getString(R.styleable.MenuItem_android_onClick); 4178262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns itemActionViewLayout = a.getResourceId(R.styleable.MenuItem_actionLayout, 0); 4188262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns itemActionViewClassName = a.getString(R.styleable.MenuItem_actionViewClass); 4198262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns itemActionProviderClassName = a.getString(R.styleable.MenuItem_actionProviderClass); 4208262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 4218262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns final boolean hasActionProvider = itemActionProviderClassName != null; 4228262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns if (hasActionProvider && itemActionViewLayout == 0 && itemActionViewClassName == null) { 4238262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns itemActionProvider = newInstance(itemActionProviderClassName, 4248262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns ACTION_PROVIDER_CONSTRUCTOR_SIGNATURE, 4258262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns mActionProviderConstructorArguments); 4268262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } else { 4278262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns if (hasActionProvider) { 4288262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns Log.w(LOG_TAG, "Ignoring attribute 'actionProviderClass'." 4298262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns + " Action view already specified."); 4308262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 4318262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns itemActionProvider = null; 4328262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 4338262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 434fd3c4560bf2348f6a06272a9f02105c9e1bf927eVladislav Kaznacheev itemContentDescription = a.getText(R.styleable.MenuItem_contentDescription); 435fd3c4560bf2348f6a06272a9f02105c9e1bf927eVladislav Kaznacheev itemTooltipText = a.getText(R.styleable.MenuItem_tooltipText); 4363a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov if (a.hasValue(R.styleable.MenuItem_iconTintMode)) { 4373a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov itemIconTintMode = DrawableUtils.parseTintMode(a.getInt( 4383a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov R.styleable.MenuItem_iconTintMode, -1), 4393a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov itemIconTintMode); 4403a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov } else { 4413a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov // Reset to null so that it's not carried over to the next item 4423a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov itemIconTintMode = null; 4433a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov } 4443a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov if (a.hasValue(R.styleable.MenuItem_iconTint)) { 4453a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov itemIconTintList = a.getColorStateList(R.styleable.MenuItem_iconTint); 4463a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov } else { 4473a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov // Reset to null so that it's not carried over to the next item 4483a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov itemIconTintList = null; 4493a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov } 450fd3c4560bf2348f6a06272a9f02105c9e1bf927eVladislav Kaznacheev 4518262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns a.recycle(); 4528262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 4538262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns itemAdded = false; 4548262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 4558262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 4568262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private char getShortcut(String shortcutString) { 4578262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns if (shortcutString == null) { 4588262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns return 0; 4598262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } else { 4608262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns return shortcutString.charAt(0); 4618262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 4628262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 4638262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 4648262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private void setItem(MenuItem item) { 4658262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns item.setChecked(itemChecked) 4668262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns .setVisible(itemVisible) 4678262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns .setEnabled(itemEnabled) 4688262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns .setCheckable(itemCheckable >= 1) 4698262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns .setTitleCondensed(itemTitleCondensed) 47009231da6d922e91d30d06876521106f13230a791Peeyush Agarwal .setIcon(itemIconResId); 4718262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 4728262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns if (itemShowAsAction >= 0) { 473458543f38db49fdcb1764f007ded33820964c3feAurimas Liutikas item.setShowAsAction(itemShowAsAction); 4748262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 4758262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 4768262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns if (itemListenerMethodName != null) { 4778262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns if (mContext.isRestricted()) { 4788262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns throw new IllegalStateException("The android:onClick attribute cannot " 4798262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns + "be used within a restricted context"); 4808262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 4818262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns item.setOnMenuItemClickListener( 482eeb589a57c069e1c1313e74de5876eceb69812a3Yigit Boyar new InflatedOnMenuItemClickListener(getRealOwner(), itemListenerMethodName)); 4838262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 4848262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 48530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell final MenuItemImpl impl = item instanceof MenuItemImpl ? (MenuItemImpl) item : null; 486592df2e7552ba6902c9750ab8453850fc9e30334Chris Banes if (itemCheckable >= 2) { 487592df2e7552ba6902c9750ab8453850fc9e30334Chris Banes if (item instanceof MenuItemImpl) { 488592df2e7552ba6902c9750ab8453850fc9e30334Chris Banes ((MenuItemImpl) item).setExclusiveCheckable(true); 489592df2e7552ba6902c9750ab8453850fc9e30334Chris Banes } else if (item instanceof MenuItemWrapperICS) { 490592df2e7552ba6902c9750ab8453850fc9e30334Chris Banes ((MenuItemWrapperICS) item).setExclusiveCheckable(true); 491592df2e7552ba6902c9750ab8453850fc9e30334Chris Banes } 4928262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 4938262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 4948262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns boolean actionViewSpecified = false; 4958262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns if (itemActionViewClassName != null) { 4968262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns View actionView = (View) newInstance(itemActionViewClassName, 4978262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns ACTION_VIEW_CONSTRUCTOR_SIGNATURE, mActionViewConstructorArguments); 498458543f38db49fdcb1764f007ded33820964c3feAurimas Liutikas item.setActionView(actionView); 4998262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns actionViewSpecified = true; 5008262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 5018262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns if (itemActionViewLayout > 0) { 5028262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns if (!actionViewSpecified) { 503458543f38db49fdcb1764f007ded33820964c3feAurimas Liutikas item.setActionView(itemActionViewLayout); 5048262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns actionViewSpecified = true; 5058262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } else { 5068262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns Log.w(LOG_TAG, "Ignoring attribute 'itemActionViewLayout'." 5078262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns + " Action view already specified."); 5088262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 5098262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 51034452b0d1034da026b8a1d6fe2fe4399844379d6Adam Powell if (itemActionProvider != null) { 51134452b0d1034da026b8a1d6fe2fe4399844379d6Adam Powell MenuItemCompat.setActionProvider(item, itemActionProvider); 5128262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 513fd3c4560bf2348f6a06272a9f02105c9e1bf927eVladislav Kaznacheev 514fd3c4560bf2348f6a06272a9f02105c9e1bf927eVladislav Kaznacheev MenuItemCompat.setContentDescription(item, itemContentDescription); 515fd3c4560bf2348f6a06272a9f02105c9e1bf927eVladislav Kaznacheev MenuItemCompat.setTooltipText(item, itemTooltipText); 51609231da6d922e91d30d06876521106f13230a791Peeyush Agarwal MenuItemCompat.setAlphabeticShortcut(item, itemAlphabeticShortcut, 51709231da6d922e91d30d06876521106f13230a791Peeyush Agarwal itemAlphabeticModifiers); 51809231da6d922e91d30d06876521106f13230a791Peeyush Agarwal MenuItemCompat.setNumericShortcut(item, itemNumericShortcut, itemNumericModifiers); 5193a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov 5203a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov if (itemIconTintMode != null) { 5213a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov MenuItemCompat.setIconTintMode(item, itemIconTintMode); 5223a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov } 5233a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov if (itemIconTintList != null) { 5243a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov MenuItemCompat.setIconTintList(item, itemIconTintList); 5253a7c6d2009dfcf99c738d70eafe146eedf6e0ac2Kirill Grouchnikov } 5268262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 5278262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 5288262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns public void addItem() { 5298262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns itemAdded = true; 5308262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns setItem(menu.add(groupId, itemId, itemCategoryOrder, itemTitle)); 5318262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 5328262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 5338262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns public SubMenu addSubMenuItem() { 5348262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns itemAdded = true; 5358262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns SubMenu subMenu = menu.addSubMenu(groupId, itemId, itemCategoryOrder, itemTitle); 5368262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns setItem(subMenu.getItem()); 5378262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns return subMenu; 5388262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 5398262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 5408262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns public boolean hasAddedItem() { 5418262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns return itemAdded; 5428262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 5438262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns 544ad1b0e82100ee31e70040d77bfa4d847b2bf0864Aurimas Liutikas @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"}) 5458262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns private <T> T newInstance(String className, Class<?>[] constructorSignature, 5468262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns Object[] arguments) { 5478262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns try { 5488262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns Class<?> clazz = mContext.getClassLoader().loadClass(className); 5498262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns Constructor<?> constructor = clazz.getConstructor(constructorSignature); 550878384f1e6de7bd9196958224ced1ecfca3be6a7Chris Banes constructor.setAccessible(true); 5518262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns return (T) constructor.newInstance(arguments); 5528262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } catch (Exception e) { 5538262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns Log.w(LOG_TAG, "Cannot instantiate class: " + className, e); 5548262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 5558262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns return null; 5568262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 5578262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns } 5588262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns} 559