| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.layoutlib.bridge.bars; |
| |
| import com.android.ide.common.rendering.api.ActionBarCallback; |
| import com.android.ide.common.rendering.api.ActionBarCallback.HomeButtonStyle; |
| import com.android.ide.common.rendering.api.ResourceValue; |
| import com.android.ide.common.rendering.api.SessionParams; |
| import com.android.layoutlib.bridge.MockView; |
| import com.android.layoutlib.bridge.android.BridgeContext; |
| |
| import android.annotation.NonNull; |
| import android.annotation.Nullable; |
| import android.view.LayoutInflater; |
| import android.view.View; |
| import android.view.ViewGroup; |
| import android.view.ViewGroup.LayoutParams; |
| import android.widget.FrameLayout; |
| import android.widget.RelativeLayout; |
| |
| /** |
| * An abstraction over two implementations of the ActionBar - framework and appcompat. |
| */ |
| public abstract class BridgeActionBar { |
| // Store a reference to the context so that we don't have to cast it repeatedly. |
| @NonNull protected final BridgeContext mBridgeContext; |
| @NonNull protected final SessionParams mParams; |
| // A Layout that contains the inflated action bar. The menu popup is added to this layout. |
| @Nullable protected final ViewGroup mEnclosingLayout; |
| |
| private final View mDecorContent; |
| private final ActionBarCallback mCallback; |
| |
| @SuppressWarnings("NotNullFieldNotInitialized") // Should be initialized by subclasses. |
| @NonNull private FrameLayout mContentRoot; |
| |
| public BridgeActionBar(@NonNull BridgeContext context, @NonNull SessionParams params) { |
| mBridgeContext = context; |
| mParams = params; |
| mCallback = params.getLayoutlibCallback().getActionBarCallback(); |
| ResourceValue layoutName = getLayoutResource(context); |
| |
| int layoutId = 0; |
| if (layoutName == null) { |
| assert false : "Unable to find the layout for Action Bar."; |
| } |
| else { |
| layoutId = context.getResourceId(layoutName.asReference(), 0); |
| } |
| if (layoutId == 0) { |
| assert false : String.format("Unable to resolve attribute \"%1$s\" of type \"%2$s\"", |
| layoutName.getName(), layoutName.getResourceType()); |
| mDecorContent = new MockView(context); |
| mEnclosingLayout = null; |
| } |
| else { |
| if (mCallback.isOverflowPopupNeeded()) { |
| // Create a RelativeLayout around the action bar, to which the overflow popup may be |
| // added. |
| mEnclosingLayout = new RelativeLayout(mBridgeContext); |
| setMatchParent(mEnclosingLayout); |
| } else { |
| mEnclosingLayout = null; |
| } |
| |
| // Inflate action bar layout. |
| mDecorContent = getInflater(context).inflate(layoutId, mEnclosingLayout, |
| mEnclosingLayout != null); |
| } |
| } |
| |
| /** |
| * Returns the Layout Resource that should be used to inflate the action bar. This layout |
| * should cover the complete screen, and have a FrameLayout included, where the content will |
| * be inflated. |
| */ |
| protected abstract ResourceValue getLayoutResource(BridgeContext context); |
| |
| protected LayoutInflater getInflater(BridgeContext context) { |
| return LayoutInflater.from(context); |
| } |
| |
| protected void setContentRoot(@NonNull FrameLayout contentRoot) { |
| mContentRoot = contentRoot; |
| } |
| |
| @NonNull |
| public FrameLayout getContentRoot() { |
| return mContentRoot; |
| } |
| |
| /** |
| * Returns the view inflated. This should contain both the ActionBar and the app content in it. |
| */ |
| protected View getDecorContent() { |
| return mDecorContent; |
| } |
| |
| /** Setup things like the title, subtitle, icon etc. */ |
| protected void setupActionBar() { |
| setTitle(); |
| setSutTitle(); |
| setIcon(); |
| setHomeAsUp(mCallback.getHomeButtonStyle() == HomeButtonStyle.SHOW_HOME_AS_UP); |
| } |
| |
| protected abstract void setTitle(CharSequence title); |
| protected abstract void setSubtitle(CharSequence subtitle); |
| protected abstract void setIcon(ResourceValue icon); |
| protected abstract void setHomeAsUp(boolean homeAsUp); |
| |
| private void setTitle() { |
| String title = mParams.getAppLabel(); |
| setTitle(title); |
| } |
| |
| private void setSutTitle() { |
| String subTitle = mCallback.getSubTitle(); |
| if (subTitle != null) { |
| setSubtitle(subTitle); |
| } |
| } |
| |
| private void setIcon() { |
| ResourceValue appIcon = mParams.getAppIcon(); |
| if (appIcon != null) { |
| setIcon(appIcon); |
| } |
| } |
| |
| public abstract void createMenuPopup(); |
| |
| /** |
| * The root view that represents the action bar and possibly the content included in it. |
| */ |
| public View getRootView() { |
| return mEnclosingLayout == null ? mDecorContent : mEnclosingLayout; |
| } |
| |
| public ActionBarCallback getCallBack() { |
| return mCallback; |
| } |
| |
| protected static void setMatchParent(View view) { |
| view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, |
| LayoutParams.MATCH_PARENT)); |
| } |
| } |