1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.view; 18 19 import android.content.Context; 20 import com.android.ide.common.rendering.api.LayoutLog; 21 import com.android.ide.common.rendering.api.ViewInfo; 22 import com.android.internal.view.menu.BridgeMenuItemImpl; 23 import com.android.internal.view.menu.MenuView; 24 import com.android.layoutlib.bridge.Bridge; 25 import com.android.layoutlib.bridge.android.BridgeContext; 26 import com.android.tools.layoutlib.annotations.LayoutlibDelegate; 27 28 import android.util.AttributeSet; 29 30 /** 31 * Delegate used to provide new implementation of a select few methods of {@link MenuInflater} 32 * <p/> 33 * Through the layoutlib_create tool, the original methods of MenuInflater have been 34 * replaced by calls to methods of the same name in this delegate class. 35 * <p/> 36 * The main purpose of the class is to get the view key from the menu xml parser and add it to 37 * the menu item. The view key is used by the IDE to match the individual view elements to the 38 * corresponding xml tag in the menu/layout file. 39 * <p/> 40 * For Menus, the views may be reused and the {@link MenuItem} is a better object to hold the 41 * view key than the {@link MenuView.ItemView}. At the time of computation of the rest of {@link 42 * ViewInfo}, we check the corresponding view key in the menu item for the view and add it 43 */ 44 public class MenuInflater_Delegate { 45 @LayoutlibDelegate registerMenu(MenuInflater thisInflater, MenuItem menuItem, AttributeSet attrs)46 /*package*/ static void registerMenu(MenuInflater thisInflater, MenuItem menuItem, 47 AttributeSet attrs) { 48 if (menuItem instanceof BridgeMenuItemImpl) { 49 Context context = thisInflater.getContext(); 50 context = BridgeContext.getBaseContext(context); 51 if (context instanceof BridgeContext) { 52 Object viewKey = BridgeInflater.getViewKeyFromParser( 53 attrs, ((BridgeContext) context), null, false); 54 ((BridgeMenuItemImpl) menuItem).setViewCookie(viewKey); 55 return; 56 } 57 } 58 59 String menuItemName = menuItem != null ? menuItem.getClass().getName() : null; 60 if (menuItemName == null || 61 !menuItemName.startsWith("android.support.") || 62 !menuItemName.startsWith("androidx.")) { 63 // This means that Bridge did not take over the instantiation of some object properly. 64 // This is most likely a bug in the LayoutLib code. 65 // We suppress this error for AppCompat menus since we do not support them in the menu 66 // editor yet. 67 Bridge.getLog().warning(LayoutLog.TAG_BROKEN, 68 "Action Bar Menu rendering may be incorrect.", null); 69 } 70 71 } 72 73 @LayoutlibDelegate registerMenu(MenuInflater thisInflater, SubMenu subMenu, AttributeSet parser)74 /*package*/ static void registerMenu(MenuInflater thisInflater, SubMenu subMenu, 75 AttributeSet parser) { 76 registerMenu(thisInflater, subMenu.getItem(), parser); 77 } 78 79 } 80