1224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta/* 2224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta * Copyright (C) 2015 The Android Open Source Project 3224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta * 4224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta * Licensed under the Apache License, Version 2.0 (the "License"); 5224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta * you may not use this file except in compliance with the License. 6224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta * You may obtain a copy of the License at 7224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta * 8224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta * http://www.apache.org/licenses/LICENSE-2.0 9224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta * 10224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta * Unless required by applicable law or agreed to in writing, software 11224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta * distributed under the License is distributed on an "AS IS" BASIS, 12224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta * See the License for the specific language governing permissions and 14224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta * limitations under the License. 15224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta */ 16224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 17224e931fed1220f175805fdec71a882649270aa7Deepanshu Guptapackage com.android.layoutlib.bridge.bars; 18224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 19224e931fed1220f175805fdec71a882649270aa7Deepanshu Guptaimport com.android.annotations.NonNull; 20224e931fed1220f175805fdec71a882649270aa7Deepanshu Guptaimport com.android.ide.common.rendering.api.ActionBarCallback; 21224e931fed1220f175805fdec71a882649270aa7Deepanshu Guptaimport com.android.ide.common.rendering.api.ActionBarCallback.HomeButtonStyle; 22224e931fed1220f175805fdec71a882649270aa7Deepanshu Guptaimport com.android.ide.common.rendering.api.RenderResources; 23224e931fed1220f175805fdec71a882649270aa7Deepanshu Guptaimport com.android.ide.common.rendering.api.ResourceValue; 24224e931fed1220f175805fdec71a882649270aa7Deepanshu Guptaimport com.android.ide.common.rendering.api.SessionParams; 25224e931fed1220f175805fdec71a882649270aa7Deepanshu Guptaimport com.android.layoutlib.bridge.android.BridgeContext; 26224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 27224e931fed1220f175805fdec71a882649270aa7Deepanshu Guptaimport android.view.LayoutInflater; 28224e931fed1220f175805fdec71a882649270aa7Deepanshu Guptaimport android.view.View; 29224e931fed1220f175805fdec71a882649270aa7Deepanshu Guptaimport android.view.ViewGroup; 30224e931fed1220f175805fdec71a882649270aa7Deepanshu Guptaimport android.view.ViewGroup.LayoutParams; 31224e931fed1220f175805fdec71a882649270aa7Deepanshu Guptaimport android.widget.FrameLayout; 32224e931fed1220f175805fdec71a882649270aa7Deepanshu Guptaimport android.widget.RelativeLayout; 33224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 34224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta/** 35224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta * An abstraction over two implementations of the ActionBar - framework and appcompat. 36224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta */ 37224e931fed1220f175805fdec71a882649270aa7Deepanshu Guptapublic abstract class BridgeActionBar { 38224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta // Store a reference to the context so that we don't have to cast it repeatedly. 39224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta @NonNull protected final BridgeContext mBridgeContext; 40224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta @NonNull protected final SessionParams mParams; 41224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta // A Layout that contains the inflated action bar. The menu popup is added to this layout. 42224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta @NonNull protected final ViewGroup mEnclosingLayout; 43224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 44224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta private final View mDecorContent; 45224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta private final ActionBarCallback mCallback; 46224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 47224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta @NonNull private FrameLayout mContentRoot; 48224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 49224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta public BridgeActionBar(@NonNull BridgeContext context, @NonNull SessionParams params, 50224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta @NonNull ViewGroup parentView) { 51224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta mBridgeContext = context; 52224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta mParams = params; 53224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta mCallback = params.getProjectCallback().getActionBarCallback(); 54224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta ResourceValue layoutName = getLayoutResource(context); 55224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta if (layoutName == null) { 56224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta throw new RuntimeException("Unable to find the layout for Action Bar."); 57224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta } 58224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta int layoutId; 59224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta if (layoutName.isFramework()) { 60224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta layoutId = context.getFrameworkResourceValue(layoutName.getResourceType(), 61224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta layoutName.getName(), 0); 62224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta } else { 63224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta layoutId = context.getProjectResourceValue(layoutName.getResourceType(), 64224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta layoutName.getName(), 0); 65224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 66224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta } 67224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta if (layoutId == 0) { 68224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta throw new RuntimeException( 69224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta String.format("Unable to resolve attribute \"%1$s\" of type \"%2$s\"", 70224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta layoutName.getName(), layoutName.getResourceType())); 71224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta } 72224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta if (mCallback.isOverflowPopupNeeded()) { 73224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta // Create a RelativeLayout around the action bar, to which the overflow popup may be 74224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta // added. 75224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta mEnclosingLayout = new RelativeLayout(mBridgeContext); 76224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta setMatchParent(mEnclosingLayout); 77224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta parentView.addView(mEnclosingLayout); 78224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta } else { 79224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta mEnclosingLayout = parentView; 80224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta } 81224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 82224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta // Inflate action bar layout. 83224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta mDecorContent = LayoutInflater.from(context).inflate(layoutId, mEnclosingLayout, true); 84224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 85224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta } 86224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 87224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta /** 88224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta * Returns the Layout Resource that should be used to inflate the action bar. This layout 89224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta * should cover the complete screen, and have a FrameLayout included, where the content will 90224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta * be inflated. 91224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta */ 92224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta protected abstract ResourceValue getLayoutResource(BridgeContext context); 93224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 94224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta protected void setContentRoot(FrameLayout contentRoot) { 95224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta mContentRoot = contentRoot; 96224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta } 97224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 98224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta @NonNull 99224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta public FrameLayout getContentRoot() { 100224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta return mContentRoot; 101224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta } 102224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 103224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta /** 104224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta * Returns the view inflated. This should contain both the ActionBar and the app content in it. 105224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta */ 106224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta protected View getDecorContent() { 107224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta return mDecorContent; 108224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta } 109224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 110224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta /** Setup things like the title, subtitle, icon etc. */ 111224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta protected void setupActionBar() { 112224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta setTitle(); 113224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta setSutTitle(); 114224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta setIcon(); 115224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta setHomeAsUp(mCallback.getHomeButtonStyle() == HomeButtonStyle.SHOW_HOME_AS_UP); 116224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta } 117224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 118224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta protected abstract void setTitle(CharSequence title); 119224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta protected abstract void setSubtitle(CharSequence subtitle); 120224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta protected abstract void setIcon(String icon); 121224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta protected abstract void setHomeAsUp(boolean homeAsUp); 122224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 123224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta private void setTitle() { 124224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta RenderResources res = mBridgeContext.getRenderResources(); 125224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 126224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta String title = mParams.getAppLabel(); 127224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta ResourceValue titleValue = res.findResValue(title, false); 128224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta if (titleValue != null && titleValue.getValue() != null) { 129224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta setTitle(titleValue.getValue()); 130224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta } else { 131224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta setTitle(title); 132224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta } 133224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta } 134224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 135224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta private void setSutTitle() { 136224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta String subTitle = mCallback.getSubTitle(); 137224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta if (subTitle != null) { 138224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta setSubtitle(subTitle); 139224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta } 140224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta } 141224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 142224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta private void setIcon() { 143224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta String appIcon = mParams.getAppIcon(); 144224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta if (appIcon != null) { 145224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta setIcon(appIcon); 146224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta } 147224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta } 148224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 149224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta public abstract void createMenuPopup(); 150224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 151224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta public ActionBarCallback getCallBack() { 152224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta return mCallback; 153224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta } 154224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta 155224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta protected static void setMatchParent(View view) { 156224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 157224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta LayoutParams.MATCH_PARENT)); 158224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta } 159224e931fed1220f175805fdec71a882649270aa7Deepanshu Gupta} 160