Loading tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java +34 −17 Original line number Original line Diff line number Diff line Loading @@ -32,7 +32,6 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException; import android.annotation.NonNull; import android.annotation.NonNull; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.ColorStateList; import android.graphics.Bitmap; import android.graphics.Bitmap; import android.graphics.Bitmap_Delegate; import android.graphics.Bitmap_Delegate; Loading Loading @@ -78,8 +77,7 @@ abstract class CustomBar extends LinearLayout { setGravity(Gravity.CENTER_HORIZONTAL); setGravity(Gravity.CENTER_HORIZONTAL); } } LayoutInflater inflater = (LayoutInflater) getContext().getSystemService( LayoutInflater inflater = LayoutInflater.from(mContext); Context.LAYOUT_INFLATER_SERVICE); XmlPullParser parser; XmlPullParser parser; try { try { Loading Loading @@ -159,7 +157,7 @@ abstract class CustomBar extends LinearLayout { protected void setStyle(String themeEntryName) { protected void setStyle(String themeEntryName) { BridgeContext bridgeContext = (BridgeContext) mContext; BridgeContext bridgeContext = getContext(); RenderResources res = bridgeContext.getRenderResources(); RenderResources res = bridgeContext.getRenderResources(); ResourceValue value = res.findItemInTheme(themeEntryName, true /*isFrameworkAttr*/); ResourceValue value = res.findItemInTheme(themeEntryName, true /*isFrameworkAttr*/); Loading Loading @@ -219,27 +217,47 @@ abstract class CustomBar extends LinearLayout { } } } } @Override public BridgeContext getContext() { return (BridgeContext) mContext; } /** /** * Given a theme attribute name, get the color referenced by it. The theme attribute may be * Find the background color for this bar from the theme attributes. Only relevant to StatusBar * used in a layout like "?attr/foo". * and NavigationBar. * <p/> * <p/> * Returns 0 if not found. * Returns 0 if not found. * * * @param colorAttrName the attribute name for the background color * @param translucentAttrName the attribute name for the translucency property of the bar. * * @throws NumberFormatException if color resolved to an invalid string. * @throws NumberFormatException if color resolved to an invalid string. */ */ protected int getThemeAttrColor(@NonNull String attrName, boolean isFramework) { protected int getBarColor(@NonNull String colorAttrName, @NonNull String translucentAttrName) { if (!Config.isGreaterOrEqual(mSimulatedPlatformVersion, LOLLIPOP)) { if (!Config.isGreaterOrEqual(mSimulatedPlatformVersion, LOLLIPOP)) { return 0; return 0; } } assert mContext instanceof BridgeContext; RenderResources renderResources = getContext().getRenderResources(); BridgeContext context = ((BridgeContext) mContext); // First check if the bar is translucent. RenderResources renderResources = context.getRenderResources(); boolean translucent = ResourceHelper.getBooleanThemeValue(renderResources, translucentAttrName, true, false); if (translucent) { // Keep in sync with R.color.system_bar_background_semi_transparent from system ui. return 0x66000000; // 40% black. } boolean transparent = ResourceHelper.getBooleanThemeValue(renderResources, "windowDrawsSystemBarBackgrounds", true, false); if (transparent) { return getColor(renderResources, colorAttrName); } return 0; } private static int getColor(RenderResources renderResources, String attr) { // From ?attr/foo to @color/bar. This is most likely an ItemResourceValue. // From ?attr/foo to @color/bar. This is most likely an ItemResourceValue. ResourceValue resource = renderResources.findItemInTheme(attrName, isFramework); ResourceValue resource = renderResources.findItemInTheme(attr, true); if (resource != null) { // Form @color/bar to the #AARRGGBB // Form @color/bar to the #AARRGGBB resource = renderResources.resolveResValue(resource); resource = renderResources.resolveResValue(resource); } if (resource != null && ResourceType.COLOR.equals(resource.getResourceType())) { if (resource != null && ResourceType.COLOR.equals(resource.getResourceType())) { return ResourceHelper.getColor(resource.getValue()); return ResourceHelper.getColor(resource.getValue()); } } Loading @@ -247,8 +265,7 @@ abstract class CustomBar extends LinearLayout { } } private ResourceValue getResourceValue(String reference) { private ResourceValue getResourceValue(String reference) { BridgeContext bridgeContext = (BridgeContext) mContext; RenderResources res = getContext().getRenderResources(); RenderResources res = bridgeContext.getRenderResources(); // find the resource // find the resource ResourceValue value = res.findResValue(reference, false); ResourceValue value = res.findResValue(reference, false); Loading tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java +3 −1 Original line number Original line Diff line number Diff line Loading @@ -31,6 +31,8 @@ public class NavigationBar extends CustomBar { /** Navigation bar background color attribute name. */ /** Navigation bar background color attribute name. */ private static final String ATTR_COLOR = "navigationBarColor"; private static final String ATTR_COLOR = "navigationBarColor"; /** Attribute for translucency property. */ public static final String ATTR_TRANSLUCENT = "windowTranslucentNavigation"; // These correspond to @dimen/navigation_side_padding in the system ui code. // These correspond to @dimen/navigation_side_padding in the system ui code. private static final int PADDING_WIDTH_DEFAULT = 36; private static final int PADDING_WIDTH_DEFAULT = 36; private static final int PADDING_WIDTH_SW360 = 40; private static final int PADDING_WIDTH_SW360 = 40; Loading Loading @@ -60,7 +62,7 @@ public class NavigationBar extends CustomBar { super(context, orientation, "/bars/navigation_bar.xml", "navigation_bar.xml", super(context, orientation, "/bars/navigation_bar.xml", "navigation_bar.xml", simulatedPlatformVersion); simulatedPlatformVersion); int color = getThemeAttrColor(ATTR_COLOR, true); int color = getBarColor(ATTR_COLOR, ATTR_TRANSLUCENT); setBackgroundColor(color == 0 ? 0xFF000000 : color); setBackgroundColor(color == 0 ? 0xFF000000 : color); // Cannot access the inside items through id because no R.id values have been // Cannot access the inside items through id because no R.id values have been Loading tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java +3 −1 Original line number Original line Diff line number Diff line Loading @@ -43,6 +43,8 @@ public class StatusBar extends CustomBar { private final int mSimulatedPlatformVersion; private final int mSimulatedPlatformVersion; /** Status bar background color attribute name. */ /** Status bar background color attribute name. */ private static final String ATTR_COLOR = "statusBarColor"; private static final String ATTR_COLOR = "statusBarColor"; /** Attribute for translucency property. */ public static final String ATTR_TRANSLUCENT = "windowTranslucentStatus"; /** /** * Constructor to be used when creating the {@link StatusBar} as a regular control. This * Constructor to be used when creating the {@link StatusBar} as a regular control. This Loading @@ -69,7 +71,7 @@ public class StatusBar extends CustomBar { // FIXME: use FILL_H? // FIXME: use FILL_H? setGravity(Gravity.START | Gravity.TOP | Gravity.RIGHT); setGravity(Gravity.START | Gravity.TOP | Gravity.RIGHT); int color = getThemeAttrColor(ATTR_COLOR, true); int color = getBarColor(ATTR_COLOR, ATTR_TRANSLUCENT); setBackgroundColor(color == 0 ? Config.getStatusBarColor(simulatedPlatformVersion) : color); setBackgroundColor(color == 0 ? Config.getStatusBarColor(simulatedPlatformVersion) : color); // Cannot access the inside items through id because no R.id values have been // Cannot access the inside items through id because no R.id values have been Loading tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java +51 −41 Original line number Original line Diff line number Diff line Loading @@ -21,7 +21,6 @@ import com.android.ide.common.rendering.api.RenderResources; import com.android.ide.common.rendering.api.ResourceValue; import com.android.ide.common.rendering.api.ResourceValue; import com.android.ide.common.rendering.api.SessionParams; import com.android.ide.common.rendering.api.SessionParams; import com.android.ide.common.rendering.api.StyleResourceValue; import com.android.ide.common.rendering.api.StyleResourceValue; import com.android.internal.util.XmlUtils; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.BridgeContext; import com.android.layoutlib.bridge.android.BridgeContext; import com.android.layoutlib.bridge.bars.AppCompatActionBar; import com.android.layoutlib.bridge.bars.AppCompatActionBar; Loading Loading @@ -91,6 +90,8 @@ class Layout extends RelativeLayout { private static final String ATTR_ACTION_BAR_SIZE = "actionBarSize"; private static final String ATTR_ACTION_BAR_SIZE = "actionBarSize"; private static final String ATTR_WINDOW_NO_TITLE = "windowNoTitle"; private static final String ATTR_WINDOW_NO_TITLE = "windowNoTitle"; private static final String ATTR_WINDOW_TITLE_SIZE = "windowTitleSize"; private static final String ATTR_WINDOW_TITLE_SIZE = "windowTitleSize"; private static final String ATTR_WINDOW_TRANSLUCENT_STATUS = StatusBar.ATTR_TRANSLUCENT; private static final String ATTR_WINDOW_TRANSLUCENT_NAV = NavigationBar.ATTR_TRANSLUCENT; private static final String PREFIX_THEME_APPCOMPAT = "Theme.AppCompat"; private static final String PREFIX_THEME_APPCOMPAT = "Theme.AppCompat"; // Default sizes // Default sizes Loading Loading @@ -131,8 +132,7 @@ class Layout extends RelativeLayout { boolean isRtl = Bridge.isLocaleRtl(getParams().getLocale()); boolean isRtl = Bridge.isLocaleRtl(getParams().getLocale()); NavigationBar navBar = null; NavigationBar navBar = null; if (Config.showOnScreenNavBar(simulatedPlatformVersion) && mBuilder.hasSoftwareButtons() && if (mBuilder.hasNavBar()) { builder.isNavBarVertical()) { navBar = createNavBar(getContext(), density, isRtl, getParams().isRtlSupported(), navBar = createNavBar(getContext(), density, isRtl, getParams().isRtlSupported(), simulatedPlatformVersion); simulatedPlatformVersion); } } Loading Loading @@ -163,25 +163,36 @@ class Layout extends RelativeLayout { @NonNull @NonNull private FrameLayout createContentFrame() { private FrameLayout createContentFrame() { FrameLayout contentRoot = new FrameLayout(getContext()); FrameLayout contentRoot = new FrameLayout(getContext()); LayoutParams params = LayoutParams params = createLayoutParams(MATCH_PARENT, MATCH_PARENT); new LayoutParams(MATCH_PARENT, MATCH_PARENT); int rule = mBuilder.isNavBarVertical() ? START_OF : ABOVE; int rule = mBuilder.isNavBarVertical() ? START_OF : ABOVE; if (mBuilder.mNavBarSize > 0) { if (mBuilder.solidBars()) { params.addRule(rule, getId(ID_NAV_BAR)); params.addRule(rule, getId(ID_NAV_BAR)); } } int below = -1; int below = -1; if (mBuilder.mActionBarSize <= 0 && mBuilder.mTitleBarSize > 0) { if (mBuilder.mActionBarSize <= 0 && mBuilder.mTitleBarSize > 0) { below = getId(ID_TITLE_BAR); below = getId(ID_TITLE_BAR); } else if (mBuilder.mStatusBarSize > 0) { } else if (mBuilder.solidBars()) { below = getId(ID_STATUS_BAR); below = getId(ID_STATUS_BAR); } } if (below != -1) { if (below != -1) { params.addRule(BELOW, below); params.addRule(BELOW, below); } } contentRoot.setLayoutParams(params); return contentRoot; return contentRoot; } } @NonNull private LayoutParams createLayoutParams(int width, int height) { DisplayMetrics metrics = getContext().getResources().getDisplayMetrics(); if (width > 0) { width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, width, metrics); } if (height > 0) { height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, height, metrics); } return new LayoutParams(width, height); } @NonNull @NonNull public FrameLayout getContentRoot() { public FrameLayout getContentRoot() { return mContentRoot; return mContentRoot; Loading @@ -208,7 +219,7 @@ class Layout extends RelativeLayout { boolean isRtlSupported, int simulatedPlatformVersion) { boolean isRtlSupported, int simulatedPlatformVersion) { StatusBar statusBar = StatusBar statusBar = new StatusBar(context, density, isRtl, isRtlSupported, simulatedPlatformVersion); new StatusBar(context, density, isRtl, isRtlSupported, simulatedPlatformVersion); LayoutParams params = new LayoutParams(MATCH_PARENT, mBuilder.mStatusBarSize); LayoutParams params = createLayoutParams(MATCH_PARENT, mBuilder.mStatusBarSize); if (mBuilder.isNavBarVertical()) { if (mBuilder.isNavBarVertical()) { params.addRule(START_OF, getId(ID_NAV_BAR)); params.addRule(START_OF, getId(ID_NAV_BAR)); } } Loading @@ -225,12 +236,12 @@ class Layout extends RelativeLayout { } else { } else { actionBar = new FrameworkActionBar(context, params); actionBar = new FrameworkActionBar(context, params); } } LayoutParams layoutParams = new LayoutParams(MATCH_PARENT, MATCH_PARENT); LayoutParams layoutParams = createLayoutParams(MATCH_PARENT, MATCH_PARENT); int rule = mBuilder.isNavBarVertical() ? START_OF : ABOVE; int rule = mBuilder.isNavBarVertical() ? START_OF : ABOVE; if (mBuilder.mNavBarSize > 0) { if (mBuilder.solidBars()) { layoutParams.addRule(rule, getId(ID_NAV_BAR)); layoutParams.addRule(rule, getId(ID_NAV_BAR)); } } if (mBuilder.mStatusBarSize > 0) { if (mBuilder.solidBars()) { layoutParams.addRule(BELOW, getId(ID_STATUS_BAR)); layoutParams.addRule(BELOW, getId(ID_STATUS_BAR)); } } actionBar.getRootView().setLayoutParams(layoutParams); actionBar.getRootView().setLayoutParams(layoutParams); Loading @@ -238,16 +249,15 @@ class Layout extends RelativeLayout { return actionBar; return actionBar; } } @NonNull @NonNull private TitleBar createTitleBar(BridgeContext context, String title, private TitleBar createTitleBar(BridgeContext context, String title, int simulatedPlatformVersion) { int simulatedPlatformVersion) { TitleBar titleBar = new TitleBar(context, title, simulatedPlatformVersion); TitleBar titleBar = new TitleBar(context, title, simulatedPlatformVersion); LayoutParams params = new LayoutParams(MATCH_PARENT, mBuilder.mTitleBarSize); LayoutParams params = createLayoutParams(MATCH_PARENT, mBuilder.mTitleBarSize); if (mBuilder.mStatusBarSize > 0) { if (mBuilder.solidBars()) { params.addRule(BELOW, getId(ID_STATUS_BAR)); params.addRule(BELOW, getId(ID_STATUS_BAR)); } } if (mBuilder.isNavBarVertical()) { if (mBuilder.isNavBarVertical() && mBuilder.solidBars()) { params.addRule(START_OF, getId(ID_NAV_BAR)); params.addRule(START_OF, getId(ID_NAV_BAR)); } } titleBar.setLayoutParams(params); titleBar.setLayoutParams(params); Loading @@ -270,7 +280,7 @@ class Layout extends RelativeLayout { boolean isVertical = mBuilder.isNavBarVertical(); boolean isVertical = mBuilder.isNavBarVertical(); int w = isVertical ? size : MATCH_PARENT; int w = isVertical ? size : MATCH_PARENT; int h = isVertical ? MATCH_PARENT : size; int h = isVertical ? MATCH_PARENT : size; LayoutParams params = new LayoutParams(w, h); LayoutParams params = createLayoutParams(w, h); params.addRule(isVertical ? ALIGN_PARENT_END : ALIGN_PARENT_BOTTOM); params.addRule(isVertical ? ALIGN_PARENT_END : ALIGN_PARENT_BOTTOM); navBar.setLayoutParams(params); navBar.setLayoutParams(params); navBar.setId(getId(ID_NAV_BAR)); navBar.setId(getId(ID_NAV_BAR)); Loading Loading @@ -306,6 +316,8 @@ class Layout extends RelativeLayout { private int mNavBarOrientation; private int mNavBarOrientation; private int mActionBarSize; private int mActionBarSize; private int mTitleBarSize; private int mTitleBarSize; private boolean mTranslucentStatus; private boolean mTranslucentNav; private Boolean mIsThemeAppCompat; private Boolean mIsThemeAppCompat; Loading @@ -313,7 +325,7 @@ class Layout extends RelativeLayout { mParams = params; mParams = params; mContext = context; mContext = context; mResources = mParams.getResources(); mResources = mParams.getResources(); mWindowIsFloating = getBooleanThemeValue(mResources, ATTR_WINDOW_FLOATING, true, true); mWindowIsFloating = ResourceHelper.getBooleanThemeValue(mResources, ATTR_WINDOW_FLOATING, true, true); findBackground(); findBackground(); findStatusBar(); findStatusBar(); Loading @@ -334,10 +346,12 @@ class Layout extends RelativeLayout { private void findStatusBar() { private void findStatusBar() { boolean windowFullScreen = boolean windowFullScreen = getBooleanThemeValue(mResources, ATTR_WINDOW_FULL_SCREEN, true, false); ResourceHelper.getBooleanThemeValue(mResources, ATTR_WINDOW_FULL_SCREEN, true, false); if (!windowFullScreen && !mWindowIsFloating) { if (!windowFullScreen && !mWindowIsFloating) { mStatusBarSize = mStatusBarSize = getDimension(ATTR_STATUS_BAR_HEIGHT, true, DEFAULT_STATUS_BAR_HEIGHT); getDimension(ATTR_STATUS_BAR_HEIGHT, true, DEFAULT_STATUS_BAR_HEIGHT); mTranslucentStatus = ResourceHelper.getBooleanThemeValue(mResources, ATTR_WINDOW_TRANSLUCENT_STATUS, true, false); } } } } Loading @@ -346,14 +360,14 @@ class Layout extends RelativeLayout { return; return; } } // Check if an actionbar is needed // Check if an actionbar is needed boolean windowActionBar = getBooleanThemeValue(mResources, ATTR_WINDOW_ACTION_BAR, boolean windowActionBar = ResourceHelper.getBooleanThemeValue(mResources, ATTR_WINDOW_ACTION_BAR, isThemeAppCompat(), true); !isThemeAppCompat(), true); if (windowActionBar) { if (windowActionBar) { mActionBarSize = getDimension(ATTR_ACTION_BAR_SIZE, true, DEFAULT_TITLE_BAR_HEIGHT); mActionBarSize = getDimension(ATTR_ACTION_BAR_SIZE, true, DEFAULT_TITLE_BAR_HEIGHT); } else { } else { // Maybe the gingerbread era title bar is needed // Maybe the gingerbread era title bar is needed boolean windowNoTitle = boolean windowNoTitle = getBooleanThemeValue(mResources, ATTR_WINDOW_NO_TITLE, true, false); ResourceHelper.getBooleanThemeValue(mResources, ATTR_WINDOW_NO_TITLE, true, false); if (!windowNoTitle) { if (!windowNoTitle) { mTitleBarSize = mTitleBarSize = getDimension(ATTR_WINDOW_TITLE_SIZE, true, DEFAULT_TITLE_BAR_HEIGHT); getDimension(ATTR_WINDOW_TITLE_SIZE, true, DEFAULT_TITLE_BAR_HEIGHT); Loading Loading @@ -381,6 +395,8 @@ class Layout extends RelativeLayout { mNavBarOrientation = barOnBottom ? LinearLayout.HORIZONTAL : VERTICAL; mNavBarOrientation = barOnBottom ? LinearLayout.HORIZONTAL : VERTICAL; mNavBarSize = getDimension(barOnBottom ? ATTR_NAV_BAR_HEIGHT : ATTR_NAV_BAR_WIDTH, mNavBarSize = getDimension(barOnBottom ? ATTR_NAV_BAR_HEIGHT : ATTR_NAV_BAR_WIDTH, true, DEFAULT_NAV_BAR_SIZE); true, DEFAULT_NAV_BAR_SIZE); mTranslucentNav = ResourceHelper.getBooleanThemeValue(mResources, ATTR_WINDOW_TRANSLUCENT_NAV, true, false); } } } } Loading @@ -396,25 +412,6 @@ class Layout extends RelativeLayout { return defaultValue; return defaultValue; } } /** * Looks for an attribute in the current theme. * * @param resources the render resources * @param name the name of the attribute * @param defaultValue the default value. * @param isFrameworkAttr if the attribute is in android namespace * @return the value of the attribute or the default one if not found. */ static boolean getBooleanThemeValue(@NonNull RenderResources resources, String name, boolean isFrameworkAttr, boolean defaultValue) { ResourceValue value = resources.findItemInTheme(name, isFrameworkAttr); value = resources.resolveResValue(value); if (value == null) { return defaultValue; } return XmlUtils.convertValueToBoolean(value.getValue(), defaultValue); } private boolean hasSoftwareButtons() { private boolean hasSoftwareButtons() { return mParams.getHardwareConfig().hasSoftwareButtons(); return mParams.getHardwareConfig().hasSoftwareButtons(); } } Loading Loading @@ -445,5 +442,18 @@ class Layout extends RelativeLayout { mIsThemeAppCompat = isThemeAppCompat; mIsThemeAppCompat = isThemeAppCompat; return isThemeAppCompat; return isThemeAppCompat; } } /** * Return if both status bar and nav bar are solid (content doesn't overlap with these * bars). */ private boolean solidBars() { return hasNavBar() && !mTranslucentNav && !mTranslucentStatus && mStatusBarSize > 0; } private boolean hasNavBar() { return Config.showOnScreenNavBar(mParams.getSimulatedPlatformVersion()) && hasSoftwareButtons() && mNavBarSize > 0; } } } } } tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -170,7 +170,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { BridgeContext context = getContext(); BridgeContext context = getContext(); // use default of true in case it's not found to use alpha by default // use default of true in case it's not found to use alpha by default mIsAlphaChannelImage = Layout.Builder.getBooleanThemeValue(params.getResources(), mIsAlphaChannelImage = ResourceHelper.getBooleanThemeValue(params.getResources(), "windowIsFloating", true, true); "windowIsFloating", true, true); mLayoutBuilder = new Layout.Builder(params, context); mLayoutBuilder = new Layout.Builder(params, context); Loading Loading
tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java +34 −17 Original line number Original line Diff line number Diff line Loading @@ -32,7 +32,6 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException; import android.annotation.NonNull; import android.annotation.NonNull; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.ColorStateList; import android.graphics.Bitmap; import android.graphics.Bitmap; import android.graphics.Bitmap_Delegate; import android.graphics.Bitmap_Delegate; Loading Loading @@ -78,8 +77,7 @@ abstract class CustomBar extends LinearLayout { setGravity(Gravity.CENTER_HORIZONTAL); setGravity(Gravity.CENTER_HORIZONTAL); } } LayoutInflater inflater = (LayoutInflater) getContext().getSystemService( LayoutInflater inflater = LayoutInflater.from(mContext); Context.LAYOUT_INFLATER_SERVICE); XmlPullParser parser; XmlPullParser parser; try { try { Loading Loading @@ -159,7 +157,7 @@ abstract class CustomBar extends LinearLayout { protected void setStyle(String themeEntryName) { protected void setStyle(String themeEntryName) { BridgeContext bridgeContext = (BridgeContext) mContext; BridgeContext bridgeContext = getContext(); RenderResources res = bridgeContext.getRenderResources(); RenderResources res = bridgeContext.getRenderResources(); ResourceValue value = res.findItemInTheme(themeEntryName, true /*isFrameworkAttr*/); ResourceValue value = res.findItemInTheme(themeEntryName, true /*isFrameworkAttr*/); Loading Loading @@ -219,27 +217,47 @@ abstract class CustomBar extends LinearLayout { } } } } @Override public BridgeContext getContext() { return (BridgeContext) mContext; } /** /** * Given a theme attribute name, get the color referenced by it. The theme attribute may be * Find the background color for this bar from the theme attributes. Only relevant to StatusBar * used in a layout like "?attr/foo". * and NavigationBar. * <p/> * <p/> * Returns 0 if not found. * Returns 0 if not found. * * * @param colorAttrName the attribute name for the background color * @param translucentAttrName the attribute name for the translucency property of the bar. * * @throws NumberFormatException if color resolved to an invalid string. * @throws NumberFormatException if color resolved to an invalid string. */ */ protected int getThemeAttrColor(@NonNull String attrName, boolean isFramework) { protected int getBarColor(@NonNull String colorAttrName, @NonNull String translucentAttrName) { if (!Config.isGreaterOrEqual(mSimulatedPlatformVersion, LOLLIPOP)) { if (!Config.isGreaterOrEqual(mSimulatedPlatformVersion, LOLLIPOP)) { return 0; return 0; } } assert mContext instanceof BridgeContext; RenderResources renderResources = getContext().getRenderResources(); BridgeContext context = ((BridgeContext) mContext); // First check if the bar is translucent. RenderResources renderResources = context.getRenderResources(); boolean translucent = ResourceHelper.getBooleanThemeValue(renderResources, translucentAttrName, true, false); if (translucent) { // Keep in sync with R.color.system_bar_background_semi_transparent from system ui. return 0x66000000; // 40% black. } boolean transparent = ResourceHelper.getBooleanThemeValue(renderResources, "windowDrawsSystemBarBackgrounds", true, false); if (transparent) { return getColor(renderResources, colorAttrName); } return 0; } private static int getColor(RenderResources renderResources, String attr) { // From ?attr/foo to @color/bar. This is most likely an ItemResourceValue. // From ?attr/foo to @color/bar. This is most likely an ItemResourceValue. ResourceValue resource = renderResources.findItemInTheme(attrName, isFramework); ResourceValue resource = renderResources.findItemInTheme(attr, true); if (resource != null) { // Form @color/bar to the #AARRGGBB // Form @color/bar to the #AARRGGBB resource = renderResources.resolveResValue(resource); resource = renderResources.resolveResValue(resource); } if (resource != null && ResourceType.COLOR.equals(resource.getResourceType())) { if (resource != null && ResourceType.COLOR.equals(resource.getResourceType())) { return ResourceHelper.getColor(resource.getValue()); return ResourceHelper.getColor(resource.getValue()); } } Loading @@ -247,8 +265,7 @@ abstract class CustomBar extends LinearLayout { } } private ResourceValue getResourceValue(String reference) { private ResourceValue getResourceValue(String reference) { BridgeContext bridgeContext = (BridgeContext) mContext; RenderResources res = getContext().getRenderResources(); RenderResources res = bridgeContext.getRenderResources(); // find the resource // find the resource ResourceValue value = res.findResValue(reference, false); ResourceValue value = res.findResValue(reference, false); Loading
tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java +3 −1 Original line number Original line Diff line number Diff line Loading @@ -31,6 +31,8 @@ public class NavigationBar extends CustomBar { /** Navigation bar background color attribute name. */ /** Navigation bar background color attribute name. */ private static final String ATTR_COLOR = "navigationBarColor"; private static final String ATTR_COLOR = "navigationBarColor"; /** Attribute for translucency property. */ public static final String ATTR_TRANSLUCENT = "windowTranslucentNavigation"; // These correspond to @dimen/navigation_side_padding in the system ui code. // These correspond to @dimen/navigation_side_padding in the system ui code. private static final int PADDING_WIDTH_DEFAULT = 36; private static final int PADDING_WIDTH_DEFAULT = 36; private static final int PADDING_WIDTH_SW360 = 40; private static final int PADDING_WIDTH_SW360 = 40; Loading Loading @@ -60,7 +62,7 @@ public class NavigationBar extends CustomBar { super(context, orientation, "/bars/navigation_bar.xml", "navigation_bar.xml", super(context, orientation, "/bars/navigation_bar.xml", "navigation_bar.xml", simulatedPlatformVersion); simulatedPlatformVersion); int color = getThemeAttrColor(ATTR_COLOR, true); int color = getBarColor(ATTR_COLOR, ATTR_TRANSLUCENT); setBackgroundColor(color == 0 ? 0xFF000000 : color); setBackgroundColor(color == 0 ? 0xFF000000 : color); // Cannot access the inside items through id because no R.id values have been // Cannot access the inside items through id because no R.id values have been Loading
tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java +3 −1 Original line number Original line Diff line number Diff line Loading @@ -43,6 +43,8 @@ public class StatusBar extends CustomBar { private final int mSimulatedPlatformVersion; private final int mSimulatedPlatformVersion; /** Status bar background color attribute name. */ /** Status bar background color attribute name. */ private static final String ATTR_COLOR = "statusBarColor"; private static final String ATTR_COLOR = "statusBarColor"; /** Attribute for translucency property. */ public static final String ATTR_TRANSLUCENT = "windowTranslucentStatus"; /** /** * Constructor to be used when creating the {@link StatusBar} as a regular control. This * Constructor to be used when creating the {@link StatusBar} as a regular control. This Loading @@ -69,7 +71,7 @@ public class StatusBar extends CustomBar { // FIXME: use FILL_H? // FIXME: use FILL_H? setGravity(Gravity.START | Gravity.TOP | Gravity.RIGHT); setGravity(Gravity.START | Gravity.TOP | Gravity.RIGHT); int color = getThemeAttrColor(ATTR_COLOR, true); int color = getBarColor(ATTR_COLOR, ATTR_TRANSLUCENT); setBackgroundColor(color == 0 ? Config.getStatusBarColor(simulatedPlatformVersion) : color); setBackgroundColor(color == 0 ? Config.getStatusBarColor(simulatedPlatformVersion) : color); // Cannot access the inside items through id because no R.id values have been // Cannot access the inside items through id because no R.id values have been Loading
tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java +51 −41 Original line number Original line Diff line number Diff line Loading @@ -21,7 +21,6 @@ import com.android.ide.common.rendering.api.RenderResources; import com.android.ide.common.rendering.api.ResourceValue; import com.android.ide.common.rendering.api.ResourceValue; import com.android.ide.common.rendering.api.SessionParams; import com.android.ide.common.rendering.api.SessionParams; import com.android.ide.common.rendering.api.StyleResourceValue; import com.android.ide.common.rendering.api.StyleResourceValue; import com.android.internal.util.XmlUtils; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.BridgeContext; import com.android.layoutlib.bridge.android.BridgeContext; import com.android.layoutlib.bridge.bars.AppCompatActionBar; import com.android.layoutlib.bridge.bars.AppCompatActionBar; Loading Loading @@ -91,6 +90,8 @@ class Layout extends RelativeLayout { private static final String ATTR_ACTION_BAR_SIZE = "actionBarSize"; private static final String ATTR_ACTION_BAR_SIZE = "actionBarSize"; private static final String ATTR_WINDOW_NO_TITLE = "windowNoTitle"; private static final String ATTR_WINDOW_NO_TITLE = "windowNoTitle"; private static final String ATTR_WINDOW_TITLE_SIZE = "windowTitleSize"; private static final String ATTR_WINDOW_TITLE_SIZE = "windowTitleSize"; private static final String ATTR_WINDOW_TRANSLUCENT_STATUS = StatusBar.ATTR_TRANSLUCENT; private static final String ATTR_WINDOW_TRANSLUCENT_NAV = NavigationBar.ATTR_TRANSLUCENT; private static final String PREFIX_THEME_APPCOMPAT = "Theme.AppCompat"; private static final String PREFIX_THEME_APPCOMPAT = "Theme.AppCompat"; // Default sizes // Default sizes Loading Loading @@ -131,8 +132,7 @@ class Layout extends RelativeLayout { boolean isRtl = Bridge.isLocaleRtl(getParams().getLocale()); boolean isRtl = Bridge.isLocaleRtl(getParams().getLocale()); NavigationBar navBar = null; NavigationBar navBar = null; if (Config.showOnScreenNavBar(simulatedPlatformVersion) && mBuilder.hasSoftwareButtons() && if (mBuilder.hasNavBar()) { builder.isNavBarVertical()) { navBar = createNavBar(getContext(), density, isRtl, getParams().isRtlSupported(), navBar = createNavBar(getContext(), density, isRtl, getParams().isRtlSupported(), simulatedPlatformVersion); simulatedPlatformVersion); } } Loading Loading @@ -163,25 +163,36 @@ class Layout extends RelativeLayout { @NonNull @NonNull private FrameLayout createContentFrame() { private FrameLayout createContentFrame() { FrameLayout contentRoot = new FrameLayout(getContext()); FrameLayout contentRoot = new FrameLayout(getContext()); LayoutParams params = LayoutParams params = createLayoutParams(MATCH_PARENT, MATCH_PARENT); new LayoutParams(MATCH_PARENT, MATCH_PARENT); int rule = mBuilder.isNavBarVertical() ? START_OF : ABOVE; int rule = mBuilder.isNavBarVertical() ? START_OF : ABOVE; if (mBuilder.mNavBarSize > 0) { if (mBuilder.solidBars()) { params.addRule(rule, getId(ID_NAV_BAR)); params.addRule(rule, getId(ID_NAV_BAR)); } } int below = -1; int below = -1; if (mBuilder.mActionBarSize <= 0 && mBuilder.mTitleBarSize > 0) { if (mBuilder.mActionBarSize <= 0 && mBuilder.mTitleBarSize > 0) { below = getId(ID_TITLE_BAR); below = getId(ID_TITLE_BAR); } else if (mBuilder.mStatusBarSize > 0) { } else if (mBuilder.solidBars()) { below = getId(ID_STATUS_BAR); below = getId(ID_STATUS_BAR); } } if (below != -1) { if (below != -1) { params.addRule(BELOW, below); params.addRule(BELOW, below); } } contentRoot.setLayoutParams(params); return contentRoot; return contentRoot; } } @NonNull private LayoutParams createLayoutParams(int width, int height) { DisplayMetrics metrics = getContext().getResources().getDisplayMetrics(); if (width > 0) { width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, width, metrics); } if (height > 0) { height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, height, metrics); } return new LayoutParams(width, height); } @NonNull @NonNull public FrameLayout getContentRoot() { public FrameLayout getContentRoot() { return mContentRoot; return mContentRoot; Loading @@ -208,7 +219,7 @@ class Layout extends RelativeLayout { boolean isRtlSupported, int simulatedPlatformVersion) { boolean isRtlSupported, int simulatedPlatformVersion) { StatusBar statusBar = StatusBar statusBar = new StatusBar(context, density, isRtl, isRtlSupported, simulatedPlatformVersion); new StatusBar(context, density, isRtl, isRtlSupported, simulatedPlatformVersion); LayoutParams params = new LayoutParams(MATCH_PARENT, mBuilder.mStatusBarSize); LayoutParams params = createLayoutParams(MATCH_PARENT, mBuilder.mStatusBarSize); if (mBuilder.isNavBarVertical()) { if (mBuilder.isNavBarVertical()) { params.addRule(START_OF, getId(ID_NAV_BAR)); params.addRule(START_OF, getId(ID_NAV_BAR)); } } Loading @@ -225,12 +236,12 @@ class Layout extends RelativeLayout { } else { } else { actionBar = new FrameworkActionBar(context, params); actionBar = new FrameworkActionBar(context, params); } } LayoutParams layoutParams = new LayoutParams(MATCH_PARENT, MATCH_PARENT); LayoutParams layoutParams = createLayoutParams(MATCH_PARENT, MATCH_PARENT); int rule = mBuilder.isNavBarVertical() ? START_OF : ABOVE; int rule = mBuilder.isNavBarVertical() ? START_OF : ABOVE; if (mBuilder.mNavBarSize > 0) { if (mBuilder.solidBars()) { layoutParams.addRule(rule, getId(ID_NAV_BAR)); layoutParams.addRule(rule, getId(ID_NAV_BAR)); } } if (mBuilder.mStatusBarSize > 0) { if (mBuilder.solidBars()) { layoutParams.addRule(BELOW, getId(ID_STATUS_BAR)); layoutParams.addRule(BELOW, getId(ID_STATUS_BAR)); } } actionBar.getRootView().setLayoutParams(layoutParams); actionBar.getRootView().setLayoutParams(layoutParams); Loading @@ -238,16 +249,15 @@ class Layout extends RelativeLayout { return actionBar; return actionBar; } } @NonNull @NonNull private TitleBar createTitleBar(BridgeContext context, String title, private TitleBar createTitleBar(BridgeContext context, String title, int simulatedPlatformVersion) { int simulatedPlatformVersion) { TitleBar titleBar = new TitleBar(context, title, simulatedPlatformVersion); TitleBar titleBar = new TitleBar(context, title, simulatedPlatformVersion); LayoutParams params = new LayoutParams(MATCH_PARENT, mBuilder.mTitleBarSize); LayoutParams params = createLayoutParams(MATCH_PARENT, mBuilder.mTitleBarSize); if (mBuilder.mStatusBarSize > 0) { if (mBuilder.solidBars()) { params.addRule(BELOW, getId(ID_STATUS_BAR)); params.addRule(BELOW, getId(ID_STATUS_BAR)); } } if (mBuilder.isNavBarVertical()) { if (mBuilder.isNavBarVertical() && mBuilder.solidBars()) { params.addRule(START_OF, getId(ID_NAV_BAR)); params.addRule(START_OF, getId(ID_NAV_BAR)); } } titleBar.setLayoutParams(params); titleBar.setLayoutParams(params); Loading @@ -270,7 +280,7 @@ class Layout extends RelativeLayout { boolean isVertical = mBuilder.isNavBarVertical(); boolean isVertical = mBuilder.isNavBarVertical(); int w = isVertical ? size : MATCH_PARENT; int w = isVertical ? size : MATCH_PARENT; int h = isVertical ? MATCH_PARENT : size; int h = isVertical ? MATCH_PARENT : size; LayoutParams params = new LayoutParams(w, h); LayoutParams params = createLayoutParams(w, h); params.addRule(isVertical ? ALIGN_PARENT_END : ALIGN_PARENT_BOTTOM); params.addRule(isVertical ? ALIGN_PARENT_END : ALIGN_PARENT_BOTTOM); navBar.setLayoutParams(params); navBar.setLayoutParams(params); navBar.setId(getId(ID_NAV_BAR)); navBar.setId(getId(ID_NAV_BAR)); Loading Loading @@ -306,6 +316,8 @@ class Layout extends RelativeLayout { private int mNavBarOrientation; private int mNavBarOrientation; private int mActionBarSize; private int mActionBarSize; private int mTitleBarSize; private int mTitleBarSize; private boolean mTranslucentStatus; private boolean mTranslucentNav; private Boolean mIsThemeAppCompat; private Boolean mIsThemeAppCompat; Loading @@ -313,7 +325,7 @@ class Layout extends RelativeLayout { mParams = params; mParams = params; mContext = context; mContext = context; mResources = mParams.getResources(); mResources = mParams.getResources(); mWindowIsFloating = getBooleanThemeValue(mResources, ATTR_WINDOW_FLOATING, true, true); mWindowIsFloating = ResourceHelper.getBooleanThemeValue(mResources, ATTR_WINDOW_FLOATING, true, true); findBackground(); findBackground(); findStatusBar(); findStatusBar(); Loading @@ -334,10 +346,12 @@ class Layout extends RelativeLayout { private void findStatusBar() { private void findStatusBar() { boolean windowFullScreen = boolean windowFullScreen = getBooleanThemeValue(mResources, ATTR_WINDOW_FULL_SCREEN, true, false); ResourceHelper.getBooleanThemeValue(mResources, ATTR_WINDOW_FULL_SCREEN, true, false); if (!windowFullScreen && !mWindowIsFloating) { if (!windowFullScreen && !mWindowIsFloating) { mStatusBarSize = mStatusBarSize = getDimension(ATTR_STATUS_BAR_HEIGHT, true, DEFAULT_STATUS_BAR_HEIGHT); getDimension(ATTR_STATUS_BAR_HEIGHT, true, DEFAULT_STATUS_BAR_HEIGHT); mTranslucentStatus = ResourceHelper.getBooleanThemeValue(mResources, ATTR_WINDOW_TRANSLUCENT_STATUS, true, false); } } } } Loading @@ -346,14 +360,14 @@ class Layout extends RelativeLayout { return; return; } } // Check if an actionbar is needed // Check if an actionbar is needed boolean windowActionBar = getBooleanThemeValue(mResources, ATTR_WINDOW_ACTION_BAR, boolean windowActionBar = ResourceHelper.getBooleanThemeValue(mResources, ATTR_WINDOW_ACTION_BAR, isThemeAppCompat(), true); !isThemeAppCompat(), true); if (windowActionBar) { if (windowActionBar) { mActionBarSize = getDimension(ATTR_ACTION_BAR_SIZE, true, DEFAULT_TITLE_BAR_HEIGHT); mActionBarSize = getDimension(ATTR_ACTION_BAR_SIZE, true, DEFAULT_TITLE_BAR_HEIGHT); } else { } else { // Maybe the gingerbread era title bar is needed // Maybe the gingerbread era title bar is needed boolean windowNoTitle = boolean windowNoTitle = getBooleanThemeValue(mResources, ATTR_WINDOW_NO_TITLE, true, false); ResourceHelper.getBooleanThemeValue(mResources, ATTR_WINDOW_NO_TITLE, true, false); if (!windowNoTitle) { if (!windowNoTitle) { mTitleBarSize = mTitleBarSize = getDimension(ATTR_WINDOW_TITLE_SIZE, true, DEFAULT_TITLE_BAR_HEIGHT); getDimension(ATTR_WINDOW_TITLE_SIZE, true, DEFAULT_TITLE_BAR_HEIGHT); Loading Loading @@ -381,6 +395,8 @@ class Layout extends RelativeLayout { mNavBarOrientation = barOnBottom ? LinearLayout.HORIZONTAL : VERTICAL; mNavBarOrientation = barOnBottom ? LinearLayout.HORIZONTAL : VERTICAL; mNavBarSize = getDimension(barOnBottom ? ATTR_NAV_BAR_HEIGHT : ATTR_NAV_BAR_WIDTH, mNavBarSize = getDimension(barOnBottom ? ATTR_NAV_BAR_HEIGHT : ATTR_NAV_BAR_WIDTH, true, DEFAULT_NAV_BAR_SIZE); true, DEFAULT_NAV_BAR_SIZE); mTranslucentNav = ResourceHelper.getBooleanThemeValue(mResources, ATTR_WINDOW_TRANSLUCENT_NAV, true, false); } } } } Loading @@ -396,25 +412,6 @@ class Layout extends RelativeLayout { return defaultValue; return defaultValue; } } /** * Looks for an attribute in the current theme. * * @param resources the render resources * @param name the name of the attribute * @param defaultValue the default value. * @param isFrameworkAttr if the attribute is in android namespace * @return the value of the attribute or the default one if not found. */ static boolean getBooleanThemeValue(@NonNull RenderResources resources, String name, boolean isFrameworkAttr, boolean defaultValue) { ResourceValue value = resources.findItemInTheme(name, isFrameworkAttr); value = resources.resolveResValue(value); if (value == null) { return defaultValue; } return XmlUtils.convertValueToBoolean(value.getValue(), defaultValue); } private boolean hasSoftwareButtons() { private boolean hasSoftwareButtons() { return mParams.getHardwareConfig().hasSoftwareButtons(); return mParams.getHardwareConfig().hasSoftwareButtons(); } } Loading Loading @@ -445,5 +442,18 @@ class Layout extends RelativeLayout { mIsThemeAppCompat = isThemeAppCompat; mIsThemeAppCompat = isThemeAppCompat; return isThemeAppCompat; return isThemeAppCompat; } } /** * Return if both status bar and nav bar are solid (content doesn't overlap with these * bars). */ private boolean solidBars() { return hasNavBar() && !mTranslucentNav && !mTranslucentStatus && mStatusBarSize > 0; } private boolean hasNavBar() { return Config.showOnScreenNavBar(mParams.getSimulatedPlatformVersion()) && hasSoftwareButtons() && mNavBarSize > 0; } } } } }
tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -170,7 +170,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { BridgeContext context = getContext(); BridgeContext context = getContext(); // use default of true in case it's not found to use alpha by default // use default of true in case it's not found to use alpha by default mIsAlphaChannelImage = Layout.Builder.getBooleanThemeValue(params.getResources(), mIsAlphaChannelImage = ResourceHelper.getBooleanThemeValue(params.getResources(), "windowIsFloating", true, true); "windowIsFloating", true, true); mLayoutBuilder = new Layout.Builder(params, context); mLayoutBuilder = new Layout.Builder(params, context); Loading