MenuInflater.java revision 904de2ec9360de2ee54b91aaf9e141d9d8ab1de1
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.view; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19cf78b3e5101349fdddbde14b3a55140f9562ae66Adam Powellimport com.android.internal.view.menu.MenuItemImpl; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParser; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserException; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 247b9c912f536925ac6ec43935d6e97506851b33d6Tor Norbyeimport android.annotation.MenuRes; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.Activity; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 27b8c19b1b33c1de2b17a51ccc9fc2893489f9f878Yigit Boyarimport android.content.ContextWrapper; 289cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banesimport android.content.res.ColorStateList; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.XmlResourceParser; 319cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banesimport android.graphics.PorterDuff; 329cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banesimport android.graphics.drawable.Drawable; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 3451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.util.Log; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Xml; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 37cf78b3e5101349fdddbde14b3a55140f9562ae66Adam Powellimport java.io.IOException; 38cf78b3e5101349fdddbde14b3a55140f9562ae66Adam Powellimport java.lang.reflect.Constructor; 39cf78b3e5101349fdddbde14b3a55140f9562ae66Adam Powellimport java.lang.reflect.Method; 4033b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This class is used to instantiate menu XML files into Menu objects. 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For performance reasons, menu inflation relies heavily on pre-processing of 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * XML files that is done at build time. Therefore, it is not currently possible 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to use MenuInflater with an XmlPullParser over a plain XML file at runtime; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * it only works with an XmlPullParser returned from a compiled resource (R. 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <em>something</em> file.) 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class MenuInflater { 5151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov private static final String LOG_TAG = "MenuInflater"; 5251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Menu tag name in XML. */ 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String XML_MENU = "menu"; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Group tag name in XML. */ 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String XML_GROUP = "group"; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Item tag name in XML. */ 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String XML_ITEM = "item"; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int NO_ID = 0; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov private static final Class<?>[] ACTION_VIEW_CONSTRUCTOR_SIGNATURE = new Class[] {Context.class}; 6551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov 6651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov private static final Class<?>[] ACTION_PROVIDER_CONSTRUCTOR_SIGNATURE = ACTION_VIEW_CONSTRUCTOR_SIGNATURE; 6751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov 6851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov private final Object[] mActionViewConstructorArguments; 6951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov 7051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov private final Object[] mActionProviderConstructorArguments; 71cf78b3e5101349fdddbde14b3a55140f9562ae66Adam Powell 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Context mContext; 739275197d35a99c3f187d18d0eda6ead3b8a32603Dianne Hackborn private Object mRealOwner; 7451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Constructs a menu inflater. 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see Activity#getMenuInflater() 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public MenuInflater(Context context) { 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 829275197d35a99c3f187d18d0eda6ead3b8a32603Dianne Hackborn mActionViewConstructorArguments = new Object[] {context}; 839275197d35a99c3f187d18d0eda6ead3b8a32603Dianne Hackborn mActionProviderConstructorArguments = mActionViewConstructorArguments; 849275197d35a99c3f187d18d0eda6ead3b8a32603Dianne Hackborn } 859275197d35a99c3f187d18d0eda6ead3b8a32603Dianne Hackborn 869275197d35a99c3f187d18d0eda6ead3b8a32603Dianne Hackborn /** 879275197d35a99c3f187d18d0eda6ead3b8a32603Dianne Hackborn * Constructs a menu inflater. 889275197d35a99c3f187d18d0eda6ead3b8a32603Dianne Hackborn * 899275197d35a99c3f187d18d0eda6ead3b8a32603Dianne Hackborn * @see Activity#getMenuInflater() 909275197d35a99c3f187d18d0eda6ead3b8a32603Dianne Hackborn * @hide 919275197d35a99c3f187d18d0eda6ead3b8a32603Dianne Hackborn */ 929275197d35a99c3f187d18d0eda6ead3b8a32603Dianne Hackborn public MenuInflater(Context context, Object realOwner) { 939275197d35a99c3f187d18d0eda6ead3b8a32603Dianne Hackborn mContext = context; 949275197d35a99c3f187d18d0eda6ead3b8a32603Dianne Hackborn mRealOwner = realOwner; 9551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov mActionViewConstructorArguments = new Object[] {context}; 9651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov mActionProviderConstructorArguments = mActionViewConstructorArguments; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inflate a menu hierarchy from the specified XML resource. Throws 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link InflateException} if there is an error. 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param menuRes Resource ID for an XML layout resource to load (e.g., 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>R.menu.main_activity</code>) 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param menu The Menu to inflate into. The items and submenus will be 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * added to this Menu. 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1087b9c912f536925ac6ec43935d6e97506851b33d6Tor Norbye public void inflate(@MenuRes int menuRes, Menu menu) { 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project XmlResourceParser parser = null; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parser = mContext.getResources().getLayout(menuRes); 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AttributeSet attrs = Xml.asAttributeSet(parser); 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parseMenu(parser, attrs, menu); 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (XmlPullParserException e) { 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new InflateException("Error inflating menu XML", e); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new InflateException("Error inflating menu XML", e); 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (parser != null) parser.close(); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called internally to fill the given menu. If a sub menu is seen, it will 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * call this recursively. 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void parseMenu(XmlPullParser parser, AttributeSet attrs, Menu menu) 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws XmlPullParserException, IOException { 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MenuState menuState = new MenuState(menu); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int eventType = parser.getEventType(); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String tagName; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean lookingForEndOfUnknownTag = false; 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String unknownTagName = null; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This loop will skip to the menu start tag 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (eventType == XmlPullParser.START_TAG) { 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tagName = parser.getName(); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tagName.equals(XML_MENU)) { 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Go to next tag 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project eventType = parser.next(); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException("Expecting menu, got " + tagName); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project eventType = parser.next(); 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (eventType != XmlPullParser.END_DOCUMENT); 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean reachedEndOfMenu = false; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (!reachedEndOfMenu) { 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (eventType) { 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case XmlPullParser.START_TAG: 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lookingForEndOfUnknownTag) { 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tagName = parser.getName(); 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tagName.equals(XML_GROUP)) { 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project menuState.readGroup(attrs); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (tagName.equals(XML_ITEM)) { 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project menuState.readItem(attrs); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (tagName.equals(XML_MENU)) { 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // A menu start tag denotes a submenu for an item 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SubMenu subMenu = menuState.addSubMenuItem(); 1681001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta registerMenu(subMenu, attrs); 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Parse the submenu into returned SubMenu 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parseMenu(parser, attrs, subMenu); 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lookingForEndOfUnknownTag = true; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unknownTagName = tagName; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case XmlPullParser.END_TAG: 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tagName = parser.getName(); 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lookingForEndOfUnknownTag && tagName.equals(unknownTagName)) { 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lookingForEndOfUnknownTag = false; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unknownTagName = null; 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (tagName.equals(XML_GROUP)) { 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project menuState.resetGroup(); 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (tagName.equals(XML_ITEM)) { 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Add the item if it hasn't been added (if the item was 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // a submenu, it would have been added already) 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!menuState.hasAddedItem()) { 189961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell if (menuState.itemActionProvider != null && 190961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell menuState.itemActionProvider.hasSubMenu()) { 1911001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta registerMenu(menuState.addSubMenuItem(), attrs); 192961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell } else { 1931001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta registerMenu(menuState.addItem(), attrs); 194961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell } 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (tagName.equals(XML_MENU)) { 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reachedEndOfMenu = true; 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case XmlPullParser.END_DOCUMENT: 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException("Unexpected end of document"); 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project eventType = parser.next(); 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2081001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta 2091001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta /** 2101001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta * The method is a hook for layoutlib to do its magic. 2111001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta * Nothing is needed outside of LayoutLib. However, it should not be deleted because it 2121001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta * appears to do nothing. 2131001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta */ 2141001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta private void registerMenu(@SuppressWarnings("unused") MenuItem item, 2151001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta @SuppressWarnings("unused") AttributeSet set) { 2161001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta } 2171001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta 2181001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta /** 2191001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta * The method is a hook for layoutlib to do its magic. 2201001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta * Nothing is needed outside of LayoutLib. However, it should not be deleted because it 2211001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta * appears to do nothing. 2221001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta */ 2231001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta private void registerMenu(@SuppressWarnings("unused") SubMenu subMenu, 2241001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta @SuppressWarnings("unused") AttributeSet set) { 2251001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta } 2261001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta 2271001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta // Needed by layoutlib. 2281001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta /*package*/ Context getContext() { 2291001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta return mContext; 2301001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta } 2311001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta 23233b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell private static class InflatedOnMenuItemClickListener 23333b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell implements MenuItem.OnMenuItemClickListener { 23451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov private static final Class<?>[] PARAM_TYPES = new Class[] { MenuItem.class }; 23533b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell 2369275197d35a99c3f187d18d0eda6ead3b8a32603Dianne Hackborn private Object mRealOwner; 23733b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell private Method mMethod; 23833b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell 2399275197d35a99c3f187d18d0eda6ead3b8a32603Dianne Hackborn public InflatedOnMenuItemClickListener(Object realOwner, String methodName) { 2409275197d35a99c3f187d18d0eda6ead3b8a32603Dianne Hackborn mRealOwner = realOwner; 2419275197d35a99c3f187d18d0eda6ead3b8a32603Dianne Hackborn Class<?> c = realOwner.getClass(); 24233b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell try { 24333b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell mMethod = c.getMethod(methodName, PARAM_TYPES); 24433b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell } catch (Exception e) { 24533b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell InflateException ex = new InflateException( 24633b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell "Couldn't resolve menu item onClick handler " + methodName + 24733b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell " in class " + c.getName()); 24833b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell ex.initCause(e); 24933b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell throw ex; 25033b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell } 25133b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell } 25233b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell 25333b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell public boolean onMenuItemClick(MenuItem item) { 25433b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell try { 25533b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell if (mMethod.getReturnType() == Boolean.TYPE) { 2569275197d35a99c3f187d18d0eda6ead3b8a32603Dianne Hackborn return (Boolean) mMethod.invoke(mRealOwner, item); 25733b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell } else { 2589275197d35a99c3f187d18d0eda6ead3b8a32603Dianne Hackborn mMethod.invoke(mRealOwner, item); 25933b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell return true; 26033b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell } 26133b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell } catch (Exception e) { 26233b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell throw new RuntimeException(e); 26333b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell } 26433b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell } 26533b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell } 266b8c19b1b33c1de2b17a51ccc9fc2893489f9f878Yigit Boyar 267b8c19b1b33c1de2b17a51ccc9fc2893489f9f878Yigit Boyar private Object getRealOwner() { 268b8c19b1b33c1de2b17a51ccc9fc2893489f9f878Yigit Boyar if (mRealOwner == null) { 269b8c19b1b33c1de2b17a51ccc9fc2893489f9f878Yigit Boyar mRealOwner = findRealOwner(mContext); 270b8c19b1b33c1de2b17a51ccc9fc2893489f9f878Yigit Boyar } 271b8c19b1b33c1de2b17a51ccc9fc2893489f9f878Yigit Boyar return mRealOwner; 272b8c19b1b33c1de2b17a51ccc9fc2893489f9f878Yigit Boyar } 273b8c19b1b33c1de2b17a51ccc9fc2893489f9f878Yigit Boyar 274b8c19b1b33c1de2b17a51ccc9fc2893489f9f878Yigit Boyar private Object findRealOwner(Object owner) { 275b8c19b1b33c1de2b17a51ccc9fc2893489f9f878Yigit Boyar if (owner instanceof Activity) { 276b8c19b1b33c1de2b17a51ccc9fc2893489f9f878Yigit Boyar return owner; 277b8c19b1b33c1de2b17a51ccc9fc2893489f9f878Yigit Boyar } 278b8c19b1b33c1de2b17a51ccc9fc2893489f9f878Yigit Boyar if (owner instanceof ContextWrapper) { 279b8c19b1b33c1de2b17a51ccc9fc2893489f9f878Yigit Boyar return findRealOwner(((ContextWrapper) owner).getBaseContext()); 280b8c19b1b33c1de2b17a51ccc9fc2893489f9f878Yigit Boyar } 281b8c19b1b33c1de2b17a51ccc9fc2893489f9f878Yigit Boyar return owner; 282b8c19b1b33c1de2b17a51ccc9fc2893489f9f878Yigit Boyar } 28333b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * State for the current menu. 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Groups can not be nested unless there is another menu (which will have 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * its state class). 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class MenuState { 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Menu menu; 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Group state is set on items as they are added, allowing an item to 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * override its group state. (As opposed to set on items at the group end tag.) 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int groupId; 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int groupCategory; 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int groupOrder; 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int groupCheckable; 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean groupVisible; 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean groupEnabled; 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean itemAdded; 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int itemId; 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int itemCategoryOrder; 3076650185caed9d08162764ed9278095e602c7ab95Adam Powell private CharSequence itemTitle; 3086650185caed9d08162764ed9278095e602c7ab95Adam Powell private CharSequence itemTitleCondensed; 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int itemIconResId; 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private char itemAlphabeticShortcut; 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private char itemNumericShortcut; 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sync to attrs.xml enum: 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * - 0: none 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * - 1: all 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * - 2: exclusive 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int itemCheckable; 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean itemChecked; 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean itemVisible; 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean itemEnabled; 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32396675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell /** 32489e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell * Sync to attrs.xml enum, values in MenuItem: 32596675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell * - 0: never 32696675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell * - 1: ifRoom 32796675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell * - 2: always 3284d9861e7ec8488634d316b20981464de2ab7b6feAdam Powell * - -1: Safe sentinel for "no value". 32996675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell */ 330fbb72fdbe58142e0f1f7ffa17f009b0d829b33c3Adam Powell private int itemShowAsAction; 331cf78b3e5101349fdddbde14b3a55140f9562ae66Adam Powell 332cf78b3e5101349fdddbde14b3a55140f9562ae66Adam Powell private int itemActionViewLayout; 333cf78b3e5101349fdddbde14b3a55140f9562ae66Adam Powell private String itemActionViewClassName; 33451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov private String itemActionProviderClassName; 33551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov 33633b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell private String itemListenerMethodName; 33733b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell 338961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell private ActionProvider itemActionProvider; 339961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell 3409cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes private ColorStateList itemIconTintList; 3419cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes private boolean itemIconTintListSet; 3429cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes private PorterDuff.Mode itemIconTintMode; 3439cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes private boolean itemIconTintModeSet; 3449cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int defaultGroupId = NO_ID; 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int defaultItemId = NO_ID; 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int defaultItemCategory = 0; 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int defaultItemOrder = 0; 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int defaultItemCheckable = 0; 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean defaultItemChecked = false; 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean defaultItemVisible = true; 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean defaultItemEnabled = true; 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public MenuState(final Menu menu) { 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.menu = menu; 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resetGroup(); 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void resetGroup() { 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project groupId = defaultGroupId; 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project groupCategory = defaultItemCategory; 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project groupOrder = defaultItemOrder; 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project groupCheckable = defaultItemCheckable; 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project groupVisible = defaultItemVisible; 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project groupEnabled = defaultItemEnabled; 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called when the parser is pointing to a group tag. 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void readGroup(AttributeSet attrs) { 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TypedArray a = mContext.obtainStyledAttributes(attrs, 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.MenuGroup); 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project groupId = a.getResourceId(com.android.internal.R.styleable.MenuGroup_id, defaultGroupId); 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project groupCategory = a.getInt(com.android.internal.R.styleable.MenuGroup_menuCategory, defaultItemCategory); 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project groupOrder = a.getInt(com.android.internal.R.styleable.MenuGroup_orderInCategory, defaultItemOrder); 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project groupCheckable = a.getInt(com.android.internal.R.styleable.MenuGroup_checkableBehavior, defaultItemCheckable); 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project groupVisible = a.getBoolean(com.android.internal.R.styleable.MenuGroup_visible, defaultItemVisible); 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project groupEnabled = a.getBoolean(com.android.internal.R.styleable.MenuGroup_enabled, defaultItemEnabled); 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called when the parser is pointing to an item tag. 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void readItem(AttributeSet attrs) { 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TypedArray a = mContext.obtainStyledAttributes(attrs, 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.MenuItem); 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Inherit attributes from the group as default value 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project itemId = a.getResourceId(com.android.internal.R.styleable.MenuItem_id, defaultItemId); 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int category = a.getInt(com.android.internal.R.styleable.MenuItem_menuCategory, groupCategory); 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int order = a.getInt(com.android.internal.R.styleable.MenuItem_orderInCategory, groupOrder); 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project itemCategoryOrder = (category & Menu.CATEGORY_MASK) | (order & Menu.USER_MASK); 3986650185caed9d08162764ed9278095e602c7ab95Adam Powell itemTitle = a.getText(com.android.internal.R.styleable.MenuItem_title); 3996650185caed9d08162764ed9278095e602c7ab95Adam Powell itemTitleCondensed = a.getText(com.android.internal.R.styleable.MenuItem_titleCondensed); 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project itemIconResId = a.getResourceId(com.android.internal.R.styleable.MenuItem_icon, 0); 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project itemAlphabeticShortcut = 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getShortcut(a.getString(com.android.internal.R.styleable.MenuItem_alphabeticShortcut)); 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project itemNumericShortcut = 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getShortcut(a.getString(com.android.internal.R.styleable.MenuItem_numericShortcut)); 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (a.hasValue(com.android.internal.R.styleable.MenuItem_checkable)) { 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Item has attribute checkable, use it 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project itemCheckable = a.getBoolean(com.android.internal.R.styleable.MenuItem_checkable, false) ? 1 : 0; 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Item does not have attribute, use the group's (group can have one more state 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for checkable that represents the exclusive checkable) 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project itemCheckable = groupCheckable; 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project itemChecked = a.getBoolean(com.android.internal.R.styleable.MenuItem_checked, defaultItemChecked); 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project itemVisible = a.getBoolean(com.android.internal.R.styleable.MenuItem_visible, groupVisible); 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project itemEnabled = a.getBoolean(com.android.internal.R.styleable.MenuItem_enabled, groupEnabled); 4164d9861e7ec8488634d316b20981464de2ab7b6feAdam Powell itemShowAsAction = a.getInt(com.android.internal.R.styleable.MenuItem_showAsAction, -1); 41733b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell itemListenerMethodName = a.getString(com.android.internal.R.styleable.MenuItem_onClick); 418cf78b3e5101349fdddbde14b3a55140f9562ae66Adam Powell itemActionViewLayout = a.getResourceId(com.android.internal.R.styleable.MenuItem_actionLayout, 0); 419cf78b3e5101349fdddbde14b3a55140f9562ae66Adam Powell itemActionViewClassName = a.getString(com.android.internal.R.styleable.MenuItem_actionViewClass); 42051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov itemActionProviderClassName = a.getString(com.android.internal.R.styleable.MenuItem_actionProviderClass); 42151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov 422961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell final boolean hasActionProvider = itemActionProviderClassName != null; 423961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell if (hasActionProvider && itemActionViewLayout == 0 && itemActionViewClassName == null) { 424961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell itemActionProvider = newInstance(itemActionProviderClassName, 425961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell ACTION_PROVIDER_CONSTRUCTOR_SIGNATURE, 426961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell mActionProviderConstructorArguments); 427961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell } else { 428961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell if (hasActionProvider) { 429961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell Log.w(LOG_TAG, "Ignoring attribute 'actionProviderClass'." 430961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell + " Action view already specified."); 431961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell } 432961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell itemActionProvider = null; 433961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell } 434961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell 4359cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes if (a.hasValueOrEmpty(com.android.internal.R.styleable.MenuItem_iconTint)) { 4369cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes itemIconTintList = a.getColorStateList( 4379cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes com.android.internal.R.styleable.MenuItem_iconTint); 4389cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes itemIconTintListSet = true; 4399cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes } else { 4409cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes itemIconTintList = null; 4419cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes itemIconTintListSet = false; 4429cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes } 4439cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes if (a.hasValueOrEmpty(com.android.internal.R.styleable.MenuItem_iconTintMode)) { 4449cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes itemIconTintMode = Drawable.parseTintMode( 4459cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes a.getInt(com.android.internal.R.styleable.MenuItem_iconTintMode, -1), null); 4469cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes itemIconTintModeSet = true; 4479cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes } else { 4489cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes itemIconTintMode = null; 4499cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes itemIconTintModeSet = false; 4509cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes } 4519cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 45351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project itemAdded = false; 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private char getShortcut(String shortcutString) { 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (shortcutString == null) { 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return shortcutString.charAt(0); 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void setItem(MenuItem item) { 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project item.setChecked(itemChecked) 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .setVisible(itemVisible) 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .setEnabled(itemEnabled) 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .setCheckable(itemCheckable >= 1) 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .setTitleCondensed(itemTitleCondensed) 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .setIcon(itemIconResId) 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .setAlphabeticShortcut(itemAlphabeticShortcut) 4734d9861e7ec8488634d316b20981464de2ab7b6feAdam Powell .setNumericShortcut(itemNumericShortcut); 4744d9861e7ec8488634d316b20981464de2ab7b6feAdam Powell 4754d9861e7ec8488634d316b20981464de2ab7b6feAdam Powell if (itemShowAsAction >= 0) { 4764d9861e7ec8488634d316b20981464de2ab7b6feAdam Powell item.setShowAsAction(itemShowAsAction); 4774d9861e7ec8488634d316b20981464de2ab7b6feAdam Powell } 47833b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell 47933b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell if (itemListenerMethodName != null) { 4805d27977f9da482627ceb19317a2cd70467aff046Adam Powell if (mContext.isRestricted()) { 4815d27977f9da482627ceb19317a2cd70467aff046Adam Powell throw new IllegalStateException("The android:onClick attribute cannot " 4825d27977f9da482627ceb19317a2cd70467aff046Adam Powell + "be used within a restricted context"); 4835d27977f9da482627ceb19317a2cd70467aff046Adam Powell } 48433b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell item.setOnMenuItemClickListener( 485b8c19b1b33c1de2b17a51ccc9fc2893489f9f878Yigit Boyar new InflatedOnMenuItemClickListener(getRealOwner(), itemListenerMethodName)); 48633b974393b6fadcefc896ec4a0f9b66724f61e9fAdam Powell } 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48896675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell if (item instanceof MenuItemImpl) { 48996675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell MenuItemImpl impl = (MenuItemImpl) item; 49096675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell if (itemCheckable >= 2) { 49196675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell impl.setExclusiveCheckable(true); 49296675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell } 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 494cf78b3e5101349fdddbde14b3a55140f9562ae66Adam Powell 49551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov boolean actionViewSpecified = false; 496cf78b3e5101349fdddbde14b3a55140f9562ae66Adam Powell if (itemActionViewClassName != null) { 49751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov View actionView = (View) newInstance(itemActionViewClassName, 49851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov ACTION_VIEW_CONSTRUCTOR_SIGNATURE, mActionViewConstructorArguments); 49951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov item.setActionView(actionView); 50051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov actionViewSpecified = true; 50151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov } 50251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov if (itemActionViewLayout > 0) { 50351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov if (!actionViewSpecified) { 50451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov item.setActionView(itemActionViewLayout); 50551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov actionViewSpecified = true; 50651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov } else { 50751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov Log.w(LOG_TAG, "Ignoring attribute 'itemActionViewLayout'." 50851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov + " Action view already specified."); 50951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov } 51051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov } 511961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell if (itemActionProvider != null) { 512961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell item.setActionProvider(itemActionProvider); 513cf78b3e5101349fdddbde14b3a55140f9562ae66Adam Powell } 5149cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes 5159cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes if (itemIconTintListSet) { 5169cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes item.setIconTintList(itemIconTintList); 5179cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes } 5189cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes if (itemIconTintModeSet) { 5199cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes item.setIconTintMode(itemIconTintMode); 5209cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes } 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 52251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov 5231001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta public MenuItem addItem() { 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project itemAdded = true; 5251001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta MenuItem item = menu.add(groupId, itemId, itemCategoryOrder, itemTitle); 5261001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta setItem(item); 5271001961f904bac5294aaf73a47c2497aa764bf7fDeepanshu Gupta return item; 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public SubMenu addSubMenuItem() { 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project itemAdded = true; 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SubMenu subMenu = menu.addSubMenu(groupId, itemId, itemCategoryOrder, itemTitle); 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setItem(subMenu.getItem()); 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return subMenu; 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean hasAddedItem() { 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return itemAdded; 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 54051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov 54151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov @SuppressWarnings("unchecked") 54251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov private <T> T newInstance(String className, Class<?>[] constructorSignature, 54351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov Object[] arguments) { 54451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov try { 54551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov Class<?> clazz = mContext.getClassLoader().loadClass(className); 54651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov Constructor<?> constructor = clazz.getConstructor(constructorSignature); 547904de2ec9360de2ee54b91aaf9e141d9d8ab1de1Alan Viverette constructor.setAccessible(true); 54851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov return (T) constructor.newInstance(arguments); 54951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov } catch (Exception e) { 55051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov Log.w(LOG_TAG, "Cannot instantiate class: " + className, e); 55151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov } 55251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov return null; 55351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov } 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 556