diff options
author | Deepanshu Gupta <deepanshu@google.com> | 2014-05-13 09:40:35 -0700 |
---|---|---|
committer | Deepanshu Gupta <deepanshu@google.com> | 2014-05-13 09:40:35 -0700 |
commit | a5461ebfaebf3337a0cf1c752334f23de145a6d1 (patch) | |
tree | 782c3d3179416b3ef5f3743b2e07477dcd402220 /tools/layoutlib | |
parent | 9053261a5413f401168d25fa4a9749723b232949 (diff) | |
parent | 6d3c4ab2456a30c5517f4ad6fb8df8d64c517beb (diff) | |
download | frameworks_base-a5461ebfaebf3337a0cf1c752334f23de145a6d1.zip frameworks_base-a5461ebfaebf3337a0cf1c752334f23de145a6d1.tar.gz frameworks_base-a5461ebfaebf3337a0cf1c752334f23de145a6d1.tar.bz2 |
resolved conflicts for merge of 6d3c4ab2 to jb-mr1-dev
Change-Id: I5c4634897882deb663f32d8148202d7c9189521d
Diffstat (limited to 'tools/layoutlib')
10 files changed, 429 insertions, 139 deletions
diff --git a/tools/layoutlib/bridge/resources/bars/action_bar.xml b/tools/layoutlib/bridge/resources/bars/action_bar.xml index 7adc5af..dcfb979 100644 --- a/tools/layoutlib/bridge/resources/bars/action_bar.xml +++ b/tools/layoutlib/bridge/resources/bars/action_bar.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <merge xmlns:android="http://schemas.android.com/apk/res/android"> - <include layout="@android:layout/action_bar_home" /> - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content"/> + +<include layout="@android:layout/screen_action_bar" /> + </merge> diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java index bf8658e..430b773 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java @@ -211,7 +211,8 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { Capability.ANIMATED_VIEW_MANIPULATION, Capability.ADAPTER_BINDING, Capability.EXTENDED_VIEWINFO, - Capability.FIXED_SCALABLE_NINE_PATCH); + Capability.FIXED_SCALABLE_NINE_PATCH, + Capability.ACTION_BAR); BridgeAssetManager.initSystem(); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java index f9f4b3a..e0f87fd 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java @@ -64,6 +64,11 @@ public class BridgeRenderSession extends RenderSession { } @Override + public List<ViewInfo> getSystemRootViews() { + return mSession.getSystemViewInfos(); + } + + @Override public Map<String, String> getDefaultProperties(Object viewObject) { return mSession.getDefaultProperties(viewObject); } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java index a1c5be4..f0c2145 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java @@ -609,7 +609,8 @@ public final class BridgeContext extends Context { } if (value != null) { - if (value.getFirst() == ResourceType.STYLE) { + if ((value.getFirst() == ResourceType.STYLE) + || (value.getFirst() == ResourceType.ATTR)) { // look for the style in the current theme, and its parent: ResourceValue item = mRenderResources.findItemInTheme(value.getSecond(), isFrameworkRes); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java new file mode 100644 index 0000000..86471f5 --- /dev/null +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2014 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.RenderResources; +import com.android.ide.common.rendering.api.ResourceValue; +import com.android.ide.common.rendering.api.SessionParams; +import com.android.internal.app.ActionBarImpl; +import com.android.internal.view.menu.MenuBuilder; +import com.android.internal.widget.ActionBarContainer; +import com.android.internal.widget.ActionBarView; +import com.android.layoutlib.bridge.Bridge; +import com.android.layoutlib.bridge.android.BridgeContext; +import com.android.layoutlib.bridge.android.BridgeXmlBlockParser; +import com.android.layoutlib.bridge.impl.ParserFactory; +import com.android.layoutlib.bridge.impl.ResourceHelper; +import com.android.resources.ResourceType; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import android.app.ActionBar; +import android.app.ActionBar.Tab; +import android.app.ActionBar.TabListener; +import android.app.FragmentTransaction; +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.MenuInflater; +import android.widget.LinearLayout; + +import java.util.ArrayList; +import java.util.List; + +public class ActionBarLayout extends LinearLayout { + + // Store another reference to the context so that we don't have to cast it repeatedly. + @SuppressWarnings("hiding") + private final BridgeContext mContext; + private final ActionBar mActionBar; + private final String mIcon; + private final String mTitle; + private final String mSubTitle; + private final boolean mSplit; + private final boolean mShowHomeAsUp; + private final List<Integer> mMenuIds; + private final MenuBuilder mMenuBuilder; + private final int mNavMode; + + public ActionBarLayout(BridgeContext context, SessionParams params) + throws XmlPullParserException { + super(context); + mIcon = params.getAppIcon(); + mTitle = params.getAppLabel(); + mContext = context; + mMenuIds = new ArrayList<Integer>(); + + ActionBarCallback callback = params.getProjectCallback().getActionBarCallback(); + mSplit = callback.getSplitActionBarWhenNarrow() & + context.getResources().getBoolean( + com.android.internal.R.bool.split_action_bar_is_narrow); + mNavMode = callback.getNavigationMode(); + // TODO: Support Navigation Drawer Indicator. + mShowHomeAsUp = callback.getHomeButtonStyle() == HomeButtonStyle.SHOW_HOME_AS_UP; + mSubTitle = callback.getSubTitle(); + + fillMenuIds(callback.getMenuIdNames()); + mMenuBuilder = new MenuBuilder(mContext); + + setOrientation(LinearLayout.HORIZONTAL); + setGravity(Gravity.CENTER_VERTICAL); + + LayoutInflater inflater = (LayoutInflater) context.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + XmlPullParser parser = ParserFactory.create( + getClass().getResourceAsStream("/bars/action_bar.xml"), "action_bar.xml"); + BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser( + parser, context, false /*platformFile*/); + try { + inflater.inflate(bridgeParser, this, true /*attachToRoot*/); + } finally { + bridgeParser.ensurePopped(); + } + mActionBar = new ActionBarImpl(this); + + setUpActionBar(); + } + + private void fillMenuIds(List<String> menuIdNames) { + for (String name : menuIdNames) { + int id = mContext.getProjectResourceValue(ResourceType.MENU, name, -1); + if (id > -1) { + mMenuIds.add(id); + } + } + } + + private void setUpActionBar() { + RenderResources res = mContext.getRenderResources(); + Drawable iconDrawable = getDrawable(res, mIcon, false /*isFramework*/); + if (iconDrawable != null) { + mActionBar.setIcon(iconDrawable); + } + ResourceValue titleValue = res.findResValue(mTitle, false /*isFramework*/); + if (titleValue != null && titleValue.getValue() != null) { + mActionBar.setTitle(titleValue.getValue()); + } else { + mActionBar.setTitle(mTitle); + } + if (mSubTitle != null) { + mActionBar.setSubtitle(mSubTitle); + } + ActionBarView actionBarView = (ActionBarView) findViewById( + Bridge.getResourceId(ResourceType.ID, "action_bar")); + actionBarView.setSplitView((ActionBarContainer) findViewById( + Bridge.getResourceId(ResourceType.ID, "split_action_bar"))); + actionBarView.setSplitActionBar(mSplit); + if (mShowHomeAsUp) { + mActionBar.setDisplayOptions(0xFF, ActionBar.DISPLAY_HOME_AS_UP); + } + setUpActionMenus(); + + mActionBar.setNavigationMode(mNavMode); + if (mNavMode == ActionBar.NAVIGATION_MODE_TABS) { + setUpTabs(3); + } + } + + private void setUpActionMenus() { + if (mMenuIds == null) { + return; + } + ActionBarView actionBarView = (ActionBarView) findViewById(Bridge.getResourceId( + ResourceType.ID, "action_bar")); + final MenuInflater inflater = new MenuInflater(mActionBar.getThemedContext()); + for (int id : mMenuIds) { + inflater.inflate(id, mMenuBuilder); + } + actionBarView.setMenu(mMenuBuilder, null /*callback*/); + } + + // TODO: Use an adapter, like List View to set up tabs. + private void setUpTabs(int num) { + for (int i = 1; i <= num; i++) { + Tab tab = mActionBar.newTab() + .setText("Tab" + i) + .setTabListener(new TabListener() { + @Override + public void onTabUnselected(Tab t, FragmentTransaction ft) { + // pass + } + @Override + public void onTabSelected(Tab t, FragmentTransaction ft) { + // pass + } + @Override + public void onTabReselected(Tab t, FragmentTransaction ft) { + // pass + } + }); + mActionBar.addTab(tab); + } + } + + private Drawable getDrawable(RenderResources res, String name, boolean isFramework) { + ResourceValue value = res.findResValue(name, isFramework); + value = res.resolveResValue(value); + if (value != null) { + return ResourceHelper.getDrawable(value, mContext); + } + return null; + } +} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java deleted file mode 100644 index 226649d..0000000 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2011 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.resources.Density; - -import org.xmlpull.v1.XmlPullParserException; - -import android.content.Context; -import android.widget.LinearLayout; -import android.widget.TextView; - -public class FakeActionBar extends CustomBar { - - private TextView mTextView; - - public FakeActionBar(Context context, Density density, String label, String icon) - throws XmlPullParserException { - super(context, density, LinearLayout.HORIZONTAL, "/bars/action_bar.xml", "action_bar.xml"); - - // Cannot access the inside items through id because no R.id values have been - // created for them. - // We do know the order though. - loadIconById(android.R.id.home, icon); - mTextView = setText(1, label); - - setStyle("actionBarStyle"); - } - - @Override - protected TextView getStyleableTextView() { - return mTextView; - } -} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java index 3d5c9c6..17715b0 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java @@ -43,12 +43,14 @@ import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.BridgeContext; import com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes; import com.android.layoutlib.bridge.android.BridgeXmlBlockParser; -import com.android.layoutlib.bridge.bars.FakeActionBar; +import com.android.layoutlib.bridge.bars.ActionBarLayout; +import com.android.layoutlib.bridge.bars.CustomBar; import com.android.layoutlib.bridge.bars.NavigationBar; import com.android.layoutlib.bridge.bars.StatusBar; import com.android.layoutlib.bridge.bars.TitleBar; import com.android.layoutlib.bridge.impl.binding.FakeAdapter; import com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter; +import com.android.resources.Density; import com.android.resources.ResourceType; import com.android.resources.ScreenOrientation; import com.android.util.Pair; @@ -134,6 +136,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { // information being returned through the API private BufferedImage mImage; private List<ViewInfo> mViewInfoList; + private List<ViewInfo> mSystemViewInfoList; private static final class PostInflateException extends Exception { private static final long serialVersionUID = 1L; @@ -226,7 +229,6 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { HardwareConfig hardwareConfig = params.getHardwareConfig(); BridgeContext context = getContext(); - // the view group that receives the window background. ViewGroup backgroundView = null; @@ -257,12 +259,8 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { topLayout.setOrientation(LinearLayout.HORIZONTAL); try { - NavigationBar navigationBar = new NavigationBar(context, - hardwareConfig.getDensity(), LinearLayout.VERTICAL); - navigationBar.setLayoutParams( - new LinearLayout.LayoutParams( - mNavigationBarSize, - LayoutParams.MATCH_PARENT)); + CustomBar navigationBar = createNavigationBar(context, + hardwareConfig.getDensity(), hardwareConfig.getScreenSize()); topLayout.addView(navigationBar); } catch (XmlPullParserException e) { @@ -294,9 +292,10 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { if (mViewRoot == null) { mViewRoot = topLayout; } else { + int topLayoutWidth = + params.getHardwareConfig().getScreenWidth() - mNavigationBarSize; LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( - LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); - layoutParams.weight = 1; + topLayoutWidth, LayoutParams.MATCH_PARENT); topLayout.setLayoutParams(layoutParams); // this is the case of soft buttons + vertical bar. @@ -307,11 +306,9 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { if (mStatusBarSize > 0) { // system bar try { - StatusBar systemBar = new StatusBar(context, hardwareConfig.getDensity()); - systemBar.setLayoutParams( - new LinearLayout.LayoutParams( - LayoutParams.MATCH_PARENT, mStatusBarSize)); - topLayout.addView(systemBar); + StatusBar statusBar = createStatusBar(context, + hardwareConfig.getDensity()); + topLayout.addView(statusBar); } catch (XmlPullParserException e) { } @@ -330,23 +327,16 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { // if the theme says no title/action bar, then the size will be 0 if (mActionBarSize > 0) { try { - FakeActionBar actionBar = new FakeActionBar(context, - hardwareConfig.getDensity(), - params.getAppLabel(), params.getAppIcon()); - actionBar.setLayoutParams( - new LinearLayout.LayoutParams( - LayoutParams.MATCH_PARENT, mActionBarSize)); + ActionBarLayout actionBar = createActionBar(context, params); backgroundLayout.addView(actionBar); + mContentRoot = (FrameLayout) actionBar.findViewById(android.R.id.content); } catch (XmlPullParserException e) { } } else if (mTitleBarSize > 0) { try { - TitleBar titleBar = new TitleBar(context, + TitleBar titleBar = createTitleBar(context, hardwareConfig.getDensity(), params.getAppLabel()); - titleBar.setLayoutParams( - new LinearLayout.LayoutParams( - LayoutParams.MATCH_PARENT, mTitleBarSize)); backgroundLayout.addView(titleBar); } catch (XmlPullParserException e) { @@ -354,22 +344,21 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { } // content frame - mContentRoot = new FrameLayout(context); - layoutParams = new LinearLayout.LayoutParams( - LayoutParams.MATCH_PARENT, 0); - layoutParams.weight = 1; - mContentRoot.setLayoutParams(layoutParams); - backgroundLayout.addView(mContentRoot); + if (mContentRoot == null) { + mContentRoot = new FrameLayout(context); + layoutParams = new LinearLayout.LayoutParams( + LayoutParams.MATCH_PARENT, 0); + layoutParams.weight = 1; + mContentRoot.setLayoutParams(layoutParams); + backgroundLayout.addView(mContentRoot); + } if (mNavigationBarOrientation == LinearLayout.HORIZONTAL && mNavigationBarSize > 0) { // system bar try { - NavigationBar navigationBar = new NavigationBar(context, - hardwareConfig.getDensity(), LinearLayout.HORIZONTAL); - navigationBar.setLayoutParams( - new LinearLayout.LayoutParams( - LayoutParams.MATCH_PARENT, mNavigationBarSize)); + CustomBar navigationBar = createNavigationBar(context, + hardwareConfig.getDensity(), hardwareConfig.getScreenSize()); topLayout.addView(navigationBar); } catch (XmlPullParserException e) { @@ -570,7 +559,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { mViewRoot.draw(mCanvas); } - mViewInfoList = startVisitingViews(mViewRoot, 0, params.getExtendedViewInfoMode()); + mSystemViewInfoList = visitAllChildren(mViewRoot, 0, params.getExtendedViewInfoMode(), false); // success! return SUCCESS.createResult(); @@ -1355,50 +1344,126 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { } } - private List<ViewInfo> startVisitingViews(View view, int offset, boolean setExtendedInfo) { - if (view == null) { - return null; - } + /** + * Visits a {@link View} and its children and generate a {@link ViewInfo} containing the + * bounds of all the views. + * + * @param view the root View + * @param offset an offset for the view bounds. + * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object. + * @param isContentFrame {@code true} if the {@code ViewInfo} to be created is part of the + * content frame. + * + * @return {@code ViewInfo} containing the bounds of the view and it children otherwise. + */ + private ViewInfo visit(View view, int offset, boolean setExtendedInfo, + boolean isContentFrame) { + ViewInfo result = createViewInfo(view, offset, setExtendedInfo, isContentFrame); - // adjust the offset to this view. - offset += view.getTop(); + if (view instanceof ViewGroup) { + ViewGroup group = ((ViewGroup) view); + result.setChildren(visitAllChildren(group, isContentFrame ? 0 : offset, + setExtendedInfo, isContentFrame)); + } + return result; + } - if (view == mContentRoot) { - return visitAllChildren(mContentRoot, offset, setExtendedInfo); + /** + * Visits all the children of a given ViewGroup and generates a list of {@link ViewInfo} + * containing the bounds of all the views. It also initializes the {@link mViewInfoList} with + * the children of the {@code mContentRoot}. + * + * @param viewGroup the root View + * @param offset an offset from the top for the content view frame. + * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object. + * @param isContentFrame {@code true} if the {@code ViewInfo} to be created is part of the + * content frame. {@code false} if the {@code ViewInfo} to be created is + * part of the system decor. + */ + private List<ViewInfo> visitAllChildren(ViewGroup viewGroup, int offset, + boolean setExtendedInfo, boolean isContentFrame) { + if (viewGroup == null) { + return null; } - // otherwise, look for mContentRoot in the children - if (view instanceof ViewGroup) { - ViewGroup group = ((ViewGroup) view); + if (!isContentFrame) { + offset += viewGroup.getTop(); + } - for (int i = 0; i < group.getChildCount(); i++) { - List<ViewInfo> list = startVisitingViews(group.getChildAt(i), offset, + int childCount = viewGroup.getChildCount(); + if (viewGroup == mContentRoot) { + List<ViewInfo> childrenWithoutOffset = new ArrayList<ViewInfo>(childCount); + List<ViewInfo> childrenWithOffset = new ArrayList<ViewInfo>(childCount); + for (int i = 0; i < childCount; i++) { + ViewInfo[] childViewInfo = visitContentRoot(viewGroup.getChildAt(i), offset, setExtendedInfo); - if (list != null) { - return list; - } + childrenWithoutOffset.add(childViewInfo[0]); + childrenWithOffset.add(childViewInfo[1]); + } + mViewInfoList = childrenWithOffset; + return childrenWithoutOffset; + } else { + List<ViewInfo> children = new ArrayList<ViewInfo>(childCount); + for (int i = 0; i < childCount; i++) { + children.add(visit(viewGroup.getChildAt(i), offset, setExtendedInfo, + isContentFrame)); } + return children; } + } - return null; + /** + * Visits the children of {@link #mContentRoot} and generates {@link ViewInfo} containing the + * bounds of all the views. It returns two {@code ViewInfo} objects with the same children, + * one with the {@code offset} and other without the {@code offset}. The offset is needed to + * get the right bounds if the {@code ViewInfo} hierarchy is accessed from + * {@code mViewInfoList}. When the hierarchy is accessed via {@code mSystemViewInfoList}, the + * offset is not needed. + * + * @return an array of length two, with ViewInfo at index 0 is without offset and ViewInfo at + * index 1 is with the offset. + */ + private ViewInfo[] visitContentRoot(View view, int offset, boolean setExtendedInfo) { + ViewInfo[] result = new ViewInfo[2]; + if (view == null) { + return result; + } + + result[0] = createViewInfo(view, 0, setExtendedInfo, true); + result[1] = createViewInfo(view, offset, setExtendedInfo, true); + if (view instanceof ViewGroup) { + List<ViewInfo> children = visitAllChildren((ViewGroup) view, 0, setExtendedInfo, true); + result[0].setChildren(children); + result[1].setChildren(children); + } + return result; } /** - * Visits a View and its children and generate a {@link ViewInfo} containing the - * bounds of all the views. - * @param view the root View - * @param offset an offset for the view bounds. - * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object. + * Creates a {@link ViewInfo} for the view. The {@code ViewInfo} corresponding to the children + * of the {@code view} are not created. Consequently, the children of {@code ViewInfo} is not + * set. + * @param offset an offset for the view bounds. Used only if view is part of the content frame. */ - private ViewInfo visit(View view, int offset, boolean setExtendedInfo) { + private ViewInfo createViewInfo(View view, int offset, boolean setExtendedInfo, + boolean isContentFrame) { if (view == null) { return null; } - ViewInfo result = new ViewInfo(view.getClass().getName(), - getContext().getViewKey(view), - view.getLeft(), view.getTop() + offset, view.getRight(), view.getBottom() + offset, - view, view.getLayoutParams()); + ViewInfo result; + if (isContentFrame) { + result = new ViewInfo(view.getClass().getName(), + getContext().getViewKey(view), + view.getLeft(), view.getTop() + offset, view.getRight(), + view.getBottom() + offset, view, view.getLayoutParams()); + + } else { + result = new SystemViewInfo(view.getClass().getName(), + getContext().getViewKey(view), + view.getLeft(), view.getTop(), view.getRight(), + view.getBottom(), view, view.getLayoutParams()); + } if (setExtendedInfo) { MarginLayoutParams marginParams = null; @@ -1413,37 +1478,68 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { marginParams != null ? marginParams.bottomMargin : 0); } - if (view instanceof ViewGroup) { - ViewGroup group = ((ViewGroup) view); - result.setChildren(visitAllChildren(group, 0 /*offset*/, setExtendedInfo)); - } - return result; } + private void invalidateRenderingSize() { + mMeasuredScreenWidth = mMeasuredScreenHeight = -1; + } + /** - * Visits all the children of a given ViewGroup generate a list of {@link ViewInfo} - * containing the bounds of all the views. - * @param view the root View - * @param offset an offset for the view bounds. - * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object. + * Creates the status bar with wifi and battery icons. */ - private List<ViewInfo> visitAllChildren(ViewGroup viewGroup, int offset, - boolean setExtendedInfo) { - if (viewGroup == null) { - return null; - } + private StatusBar createStatusBar(BridgeContext context, Density density) + throws XmlPullParserException { + StatusBar statusBar = new StatusBar(context, density); + statusBar.setLayoutParams( + new LinearLayout.LayoutParams( + LayoutParams.MATCH_PARENT, mStatusBarSize)); + return statusBar; + } - List<ViewInfo> children = new ArrayList<ViewInfo>(); - for (int i = 0; i < viewGroup.getChildCount(); i++) { - children.add(visit(viewGroup.getChildAt(i), offset, setExtendedInfo)); + /** + * Creates the navigation bar with back, home and recent buttons. + * + * @param isRtl true if the current locale is right-to-left + * @param isRtlSupported true is the project manifest declares that the application + * is RTL aware. + */ + private CustomBar createNavigationBar(BridgeContext context, Density density, ScreenSize size) + throws XmlPullParserException { + CustomBar navigationBar; + if (size == ScreenSize.XLARGE) { + navigationBar = new TabletSystemBar(context, density); + } else { + navigationBar = new NavigationBar(context, density, + mNavigationBarOrientation); + } + if (mNavigationBarOrientation == LinearLayout.VERTICAL) { + navigationBar.setLayoutParams(new LinearLayout.LayoutParams(mNavigationBarSize, + LayoutParams.MATCH_PARENT)); + } else { + navigationBar.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, + mNavigationBarSize)); } - return children; + return navigationBar; } + private TitleBar createTitleBar(BridgeContext context, Density density, String title) + throws XmlPullParserException { + TitleBar titleBar = new TitleBar(context, density, title); + titleBar.setLayoutParams( + new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, mTitleBarSize)); + return titleBar; + } - private void invalidateRenderingSize() { - mMeasuredScreenWidth = mMeasuredScreenHeight = -1; + /** + * Creates the action bar. Also queries the project callback for missing information. + */ + private ActionBarLayout createActionBar(BridgeContext context, SessionParams params) + throws XmlPullParserException { + ActionBarLayout actionBar = new ActionBarLayout(context, params); + actionBar.setLayoutParams(new LinearLayout.LayoutParams( + LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); + return actionBar; } public BufferedImage getImage() { @@ -1458,6 +1554,10 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { return mViewInfoList; } + public List<ViewInfo> getSystemViewInfos() { + return mSystemViewInfoList; + } + public Map<String, String> getDefaultProperties(Object viewObject) { return getContext().getDefaultPropMap(viewObject); } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java index 6dcb693..adb0937 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java @@ -165,6 +165,9 @@ public final class ResourceHelper { * @param context the current context */ public static Drawable getDrawable(ResourceValue value, BridgeContext context) { + if (value == null) { + return null; + } String stringValue = value.getValue(); if (RenderResources.REFERENCE_NULL.equals(stringValue)) { return null; diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/SystemViewInfo.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/SystemViewInfo.java new file mode 100644 index 0000000..5c267df --- /dev/null +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/SystemViewInfo.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014 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.impl; + +import com.android.ide.common.rendering.api.ViewInfo; + +public class SystemViewInfo extends ViewInfo { + + public SystemViewInfo(String name, Object cookie, int left, int top, + int right, int bottom) { + super(name, cookie, left, top, right, bottom); + } + + public SystemViewInfo(String name, Object cookie, int left, int top, + int right, int bottom, Object viewObject, Object layoutParamsObject) { + super(name, cookie, left, top, right, bottom, viewObject, + layoutParamsObject); + } + + @Override + public boolean isSystemView() { + return true; + } +} diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java index 11433aa..964e2f3 100644 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java @@ -113,6 +113,7 @@ public class Main { "android.pim.*", // for datepicker "android.os.*", // for android.os.Handler "android.database.ContentObserver", // for Digital clock + "com.android.internal.view.menu.ActionMenu", }, excludeClasses); aa.analyze(); |