| /* |
| * 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.annotations.NonNull; |
| import com.android.ide.common.rendering.api.ActionBarCallback; |
| import com.android.ide.common.rendering.api.ActionBarCallback.HomeButtonStyle; |
| import com.android.ide.common.rendering.api.RenderResources; |
| import com.android.ide.common.rendering.api.ResourceValue; |
| import com.android.ide.common.rendering.api.SessionParams; |
| import com.android.layoutlib.bridge.android.BridgeContext; |
| |
| 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. |
| @NonNull protected final ViewGroup mEnclosingLayout; |
| |
| private final View mDecorContent; |
| private final ActionBarCallback mCallback; |
| |
| @SuppressWarnings("NullableProblems") // Should be initialized by subclasses. |
| @NonNull private FrameLayout mContentRoot; |
| |
| public BridgeActionBar(@NonNull BridgeContext context, @NonNull SessionParams params, |
| @NonNull ViewGroup parentView) { |
| mBridgeContext = context; |
| mParams = params; |
| mCallback = params.getLayoutlibCallback().getActionBarCallback(); |
| ResourceValue layoutName = getLayoutResource(context); |
| if (layoutName == null) { |
| throw new RuntimeException("Unable to find the layout for Action Bar."); |
| } |
| int layoutId; |
| if (layoutName.isFramework()) { |
| layoutId = context.getFrameworkResourceValue(layoutName.getResourceType(), |
| layoutName.getName(), 0); |
| } else { |
| layoutId = context.getProjectResourceValue(layoutName.getResourceType(), |
| layoutName.getName(), 0); |
| |
| } |
| if (layoutId == 0) { |
| throw new RuntimeException( |
| String.format("Unable to resolve attribute \"%1$s\" of type \"%2$s\"", |
| layoutName.getName(), layoutName.getResourceType())); |
| } |
| if (mCallback.isOverflowPopupNeeded()) { |
| // Create a RelativeLayout around the action bar, to which the overflow popup may be |
| // added. |
| mEnclosingLayout = new RelativeLayout(mBridgeContext); |
| setMatchParent(mEnclosingLayout); |
| parentView.addView(mEnclosingLayout); |
| } else { |
| mEnclosingLayout = parentView; |
| } |
| |
| // Inflate action bar layout. |
| mDecorContent = getInflater(context).inflate(layoutId, mEnclosingLayout, true); |
| |
| } |
| |
| /** |
| * 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(String icon); |
| protected abstract void setHomeAsUp(boolean homeAsUp); |
| |
| private void setTitle() { |
| RenderResources res = mBridgeContext.getRenderResources(); |
| |
| String title = mParams.getAppLabel(); |
| ResourceValue titleValue = res.findResValue(title, false); |
| if (titleValue != null && titleValue.getValue() != null) { |
| setTitle(titleValue.getValue()); |
| } else { |
| setTitle(title); |
| } |
| } |
| |
| private void setSutTitle() { |
| String subTitle = mCallback.getSubTitle(); |
| if (subTitle != null) { |
| setSubtitle(subTitle); |
| } |
| } |
| |
| private void setIcon() { |
| String appIcon = mParams.getAppIcon(); |
| if (appIcon != null) { |
| setIcon(appIcon); |
| } |
| } |
| |
| public abstract void createMenuPopup(); |
| |
| public ActionBarCallback getCallBack() { |
| return mCallback; |
| } |
| |
| protected static void setMatchParent(View view) { |
| view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, |
| LayoutParams.MATCH_PARENT)); |
| } |
| } |