diff options
author | Abodunrinwa Toki <toki@google.com> | 2015-06-23 20:36:52 -0700 |
---|---|---|
committer | Abodunrinwa Toki <toki@google.com> | 2015-06-25 15:47:26 -0700 |
commit | 079f33bca029c440ec6e788d6b3185f850f57973 (patch) | |
tree | 9c410d6298caeb31b860baac8c76b55501e5215d | |
parent | e71c6e3832a963ed3cfa8c124374799f774eccb3 (diff) | |
download | frameworks_base-079f33bca029c440ec6e788d6b3185f850f57973.zip frameworks_base-079f33bca029c440ec6e788d6b3185f850f57973.tar.gz frameworks_base-079f33bca029c440ec6e788d6b3185f850f57973.tar.bz2 |
Enforce FloatingToolbar themes.
This ensures that theme attribute values that affect the look and
feel of the FloatingToolbar views are the ones specified in the
framework.
The aim is to avoid apps modifying the toolbar's look and feel in
unexpected ways by overriding Theme attributes.
Bug: 21957785
Change-Id: Idd472b4e8511f0a039cd07f98b1fd3ce93ae97fa
-rw-r--r-- | core/java/com/android/internal/widget/FloatingToolbar.java | 47 | ||||
-rw-r--r-- | core/res/res/layout/floating_popup_menu_button.xml | 3 | ||||
-rw-r--r-- | core/res/res/values/attrs.xml | 3 | ||||
-rwxr-xr-x | core/res/res/values/symbols.xml | 1 | ||||
-rw-r--r-- | core/res/res/values/themes.xml | 2 |
5 files changed, 34 insertions, 22 deletions
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java index 523663c..32a145c 100644 --- a/core/java/com/android/internal/widget/FloatingToolbar.java +++ b/core/java/com/android/internal/widget/FloatingToolbar.java @@ -23,6 +23,7 @@ import android.animation.ObjectAnimator; import android.content.ComponentCallbacks; import android.content.Context; import android.content.res.Configuration; +import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.Point; import android.graphics.Rect; @@ -30,6 +31,7 @@ import android.graphics.Region; import android.graphics.drawable.ColorDrawable; import android.text.TextUtils; import android.util.Size; +import android.view.ContextThemeWrapper; import android.view.Gravity; import android.view.LayoutInflater; import android.view.Menu; @@ -108,8 +110,10 @@ public final class FloatingToolbar { * Initializes a floating toolbar. */ public FloatingToolbar(Context context, Window window) { - mContext = Preconditions.checkNotNull(context); - mPopup = new FloatingToolbarPopup(window.getDecorView()); + Preconditions.checkNotNull(context); + Preconditions.checkNotNull(window); + mContext = applyDefaultTheme(context); + mPopup = new FloatingToolbarPopup(mContext, window.getDecorView()); } /** @@ -276,6 +280,7 @@ public final class FloatingToolbar { public static final int OVERFLOW_DIRECTION_UP = 0; public static final int OVERFLOW_DIRECTION_DOWN = 1; + private final Context mContext; private final View mParent; private final PopupWindow mPopupWindow; private final ViewGroup mContentContainer; @@ -375,9 +380,10 @@ public final class FloatingToolbar { * @param parent A parent view to get the {@link android.view.View#getWindowToken()} token * from. */ - public FloatingToolbarPopup(View parent) { + public FloatingToolbarPopup(Context context, View parent) { mParent = Preconditions.checkNotNull(parent); - mContentContainer = createContentContainer(parent.getContext()); + mContext = Preconditions.checkNotNull(context); + mContentContainer = createContentContainer(context); mPopupWindow = createPopupWindow(mContentContainer); mDismissAnimation = createExitAnimation( mContentContainer, @@ -415,7 +421,7 @@ public final class FloatingToolbar { mContentContainer.removeAllViews(); if (mMainPanel == null) { - mMainPanel = new FloatingToolbarMainPanel(mParent.getContext(), mOpenOverflow); + mMainPanel = new FloatingToolbarMainPanel(mContext, mOpenOverflow); } List<MenuItem> overflowMenuItems = mMainPanel.layoutMenuItems(menuItems, getToolbarWidth(suggestedWidth)); @@ -423,7 +429,7 @@ public final class FloatingToolbar { if (!overflowMenuItems.isEmpty()) { if (mOverflowPanel == null) { mOverflowPanel = - new FloatingToolbarOverflowPanel(mParent.getContext(), mCloseOverflow); + new FloatingToolbarOverflowPanel(mContext, mCloseOverflow); } mOverflowPanel.setMenuItems(overflowMenuItems); mOverflowPanel.setOnMenuItemClickListener(menuItemClickListener); @@ -540,7 +546,7 @@ public final class FloatingToolbar { * Returns the context this popup is running in. */ public Context getContext() { - return mContentContainer.getContext(); + return mContext; } private void refreshCoordinatesAndOverflowDirection(Rect contentRect) { @@ -562,7 +568,7 @@ public final class FloatingToolbar { } else if (availableHeightBelowContent >= getToolbarHeightWithVerticalMargin()) { // There is enough space at the bottom of the content. y = contentRect.bottom; - } else if (availableHeightBelowContent >= getEstimatedToolbarHeight(getContext())) { + } else if (availableHeightBelowContent >= getEstimatedToolbarHeight(mContext)) { // Just enough space to fit the toolbar with no vertical margins. y = contentRect.bottom - mMarginVertical; } else { @@ -621,7 +627,7 @@ public final class FloatingToolbar { } private int getToolbarHeightWithVerticalMargin() { - return getEstimatedToolbarHeight(mParent.getContext()) + mMarginVertical * 2; + return getEstimatedToolbarHeight(mContext) + mMarginVertical * 2; } /** @@ -1477,6 +1483,17 @@ public final class FloatingToolbar { return animation; } + /** + * Returns a re-themed context with controlled look and feel for views. + */ + private static Context applyDefaultTheme(Context originalContext) { + TypedArray a = originalContext.obtainStyledAttributes(new int[]{R.attr.isLightTheme}); + boolean isLightTheme = a.getBoolean(0, true); + int themeId = isLightTheme ? R.style.Theme_Material_Light : R.style.Theme_Material; + a.recycle(); + return new ContextThemeWrapper(originalContext, themeId); + } + private static int getEstimatedToolbarHeight(Context context) { return context.getResources().getDimensionPixelSize(R.dimen.floating_toolbar_height); } @@ -1486,18 +1503,6 @@ public final class FloatingToolbar { .getDimensionPixelSize(R.dimen.floating_toolbar_menu_button_minimum_width); } - private static int getAdjustedToolbarWidth(Context context, int width) { - int maximumWidth = getScreenWidth(context) - 2 * context.getResources() - .getDimensionPixelSize(R.dimen.floating_toolbar_horizontal_margin); - - if (width <= 0 || width > maximumWidth) { - int defaultWidth = context.getResources() - .getDimensionPixelSize(R.dimen.floating_toolbar_preferred_width); - width = Math.min(defaultWidth, maximumWidth); - } - return width; - } - /** * Returns the device's screen width. */ diff --git a/core/res/res/layout/floating_popup_menu_button.xml b/core/res/res/layout/floating_popup_menu_button.xml index 1b58ce5..482f91f 100644 --- a/core/res/res/layout/floating_popup_menu_button.xml +++ b/core/res/res/layout/floating_popup_menu_button.xml @@ -18,7 +18,8 @@ <Button xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="match_parent" - android:minWidth="@dimen/floating_toolbar_menu_button_side_padding" + android:minWidth="@dimen/floating_toolbar_menu_button_minimum_width" + android:minHeight="@dimen/floating_toolbar_height" android:paddingStart="@dimen/floating_toolbar_menu_button_side_padding" android:paddingEnd="@dimen/floating_toolbar_menu_button_side_padding" android:paddingTop="0dp" diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 33c9c60..fd47d49 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -27,6 +27,9 @@ <!-- ============== --> <eat-comment /> + <!-- Specifies that a theme has a light background with dark text on top. --> + <attr name="isLightTheme" format="boolean" /> + <!-- Default color of foreground imagery. --> <attr name="colorForeground" format="color" /> <!-- Default color of foreground imagery on an inverted background. --> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 3a1a156..5c42d04 100755 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -240,6 +240,7 @@ <java-symbol type="attr" name="windowFixedHeightMajor" /> <java-symbol type="attr" name="windowFixedHeightMinor" /> <java-symbol type="attr" name="accessibilityFocusedDrawable"/> + <java-symbol type="attr" name="isLightTheme"/> <java-symbol type="bool" name="action_bar_embed_tabs" /> <java-symbol type="bool" name="action_bar_embed_tabs_pre_jb" /> diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml index b7acdd4..c230645 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -42,6 +42,7 @@ please see themes_device_defaults.xml. --> <style name="Theme"> + <item name="isLightTheme">false</item> <item name="colorForeground">@color/bright_foreground_dark</item> <item name="colorForegroundInverse">@color/bright_foreground_dark_inverse</item> <item name="colorBackground">@color/background_dark</item> @@ -472,6 +473,7 @@ please see themes_device_defaults.xml. background will be a light color. <p>This is designed for API level 10 and lower.</p>--> <style name="Theme.Light"> + <item name="isLightTheme">true</item> <item name="windowBackground">@drawable/screen_background_selector_light</item> <item name="windowClipToOutline">false</item> |