• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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 com.android.layoutlib.bridge.bars;
18 
19 import com.android.ide.common.rendering.api.ActionBarCallback;
20 import com.android.ide.common.rendering.api.ActionBarCallback.HomeButtonStyle;
21 import com.android.ide.common.rendering.api.ResourceValue;
22 import com.android.ide.common.rendering.api.SessionParams;
23 import com.android.layoutlib.bridge.MockView;
24 import com.android.layoutlib.bridge.android.BridgeContext;
25 
26 import android.annotation.NonNull;
27 import android.annotation.Nullable;
28 import android.view.LayoutInflater;
29 import android.view.View;
30 import android.view.ViewGroup;
31 import android.view.ViewGroup.LayoutParams;
32 import android.widget.FrameLayout;
33 import android.widget.RelativeLayout;
34 
35 /**
36  * An abstraction over two implementations of the ActionBar - framework and appcompat.
37  */
38 public abstract class BridgeActionBar {
39     // Store a reference to the context so that we don't have to cast it repeatedly.
40     @NonNull protected final BridgeContext mBridgeContext;
41     @NonNull
42     private final SessionParams mParams;
43     // A Layout that contains the inflated action bar. The menu popup is added to this layout.
44     @Nullable protected final ViewGroup mEnclosingLayout;
45 
46     private final View mDecorContent;
47     private final ActionBarCallback mCallback;
48 
49     @SuppressWarnings("NotNullFieldNotInitialized") // Should be initialized by subclasses.
50     @NonNull private FrameLayout mContentRoot;
51 
BridgeActionBar(@onNull BridgeContext context, @NonNull SessionParams params)52     protected BridgeActionBar(@NonNull BridgeContext context, @NonNull SessionParams params) {
53         mBridgeContext = context;
54         mParams = params;
55         mCallback = params.getLayoutlibCallback().getActionBarCallback();
56         ResourceValue layoutName = getLayoutResource(context);
57 
58         int layoutId = 0;
59         if (layoutName == null) {
60             assert false : "Unable to find the layout for Action Bar.";
61         }
62         else {
63             layoutId = context.getResourceId(layoutName.asReference(), 0);
64         }
65         if (layoutId == 0) {
66             assert false : String.format("Unable to resolve attribute \"%1$s\" of type \"%2$s\"",
67                     layoutName.getName(), layoutName.getResourceType());
68             mDecorContent = new MockView(context);
69             mEnclosingLayout = null;
70         }
71         else {
72             if (mCallback.isOverflowPopupNeeded()) {
73                 // Create a RelativeLayout around the action bar, to which the overflow popup may be
74                 // added.
75                 mEnclosingLayout = new RelativeLayout(mBridgeContext);
76                 setMatchParent(mEnclosingLayout);
77             } else {
78                 mEnclosingLayout = null;
79             }
80 
81             // Inflate action bar layout.
82             mDecorContent = getInflater(context).inflate(layoutId, mEnclosingLayout,
83                     mEnclosingLayout != null);
84         }
85     }
86 
87     /**
88      * Returns the Layout Resource that should be used to inflate the action bar. This layout
89      * should cover the complete screen, and have a FrameLayout included, where the content will
90      * be inflated.
91      */
getLayoutResource(BridgeContext context)92     protected abstract ResourceValue getLayoutResource(BridgeContext context);
93 
getInflater(BridgeContext context)94     protected LayoutInflater getInflater(BridgeContext context) {
95         return LayoutInflater.from(context);
96     }
97 
setContentRoot(@onNull FrameLayout contentRoot)98     protected void setContentRoot(@NonNull FrameLayout contentRoot) {
99         mContentRoot = contentRoot;
100     }
101 
102     @NonNull
getContentRoot()103     public FrameLayout getContentRoot() {
104         return mContentRoot;
105     }
106 
107     /**
108      * Returns the view inflated. This should contain both the ActionBar and the app content in it.
109      */
getDecorContent()110     protected View getDecorContent() {
111         return mDecorContent;
112     }
113 
114     /** Setup things like the title, subtitle, icon etc. */
setupActionBar()115     protected void setupActionBar() {
116         setTitle();
117         setSutTitle();
118         setIcon();
119         setHomeAsUp(mCallback.getHomeButtonStyle() == HomeButtonStyle.SHOW_HOME_AS_UP);
120     }
121 
setTitle(CharSequence title)122     protected abstract void setTitle(CharSequence title);
setSubtitle(CharSequence subtitle)123     protected abstract void setSubtitle(CharSequence subtitle);
setIcon(ResourceValue icon)124     protected abstract void setIcon(ResourceValue icon);
setHomeAsUp(boolean homeAsUp)125     protected abstract void setHomeAsUp(boolean homeAsUp);
126 
setTitle()127     private void setTitle() {
128         String title = mParams.getAppLabel();
129         setTitle(title);
130     }
131 
setSutTitle()132     private void setSutTitle() {
133         String subTitle = mCallback.getSubTitle();
134         if (subTitle != null) {
135             setSubtitle(subTitle);
136         }
137     }
138 
setIcon()139     private void setIcon() {
140         ResourceValue appIcon = mParams.getAppIcon();
141         if (appIcon != null) {
142             setIcon(appIcon);
143         }
144     }
145 
createMenuPopup()146     public abstract void createMenuPopup();
147 
148     /**
149      * The root view that represents the action bar and possibly the content included in it.
150      */
getRootView()151     public View getRootView() {
152         return mEnclosingLayout == null ? mDecorContent : mEnclosingLayout;
153     }
154 
getCallBack()155     protected ActionBarCallback getCallBack() {
156         return mCallback;
157     }
158 
setMatchParent(View view)159     protected static void setMatchParent(View view) {
160         view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
161                 LayoutParams.MATCH_PARENT));
162     }
163 }
164