diff options
author | Abodunrinwa Toki <toki@google.com> | 2015-03-27 17:16:57 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-03-27 17:16:59 +0000 |
commit | 1e650e26a7bb2f02635530a46ecd715f9911d40e (patch) | |
tree | 7b8f3e82c38b6e7d02e4241991e66c0e30aabf26 | |
parent | 4bc50fd772c83a2a4871c50dd6268e6d97000c9d (diff) | |
parent | 0c7ed2886e6d17cacc9c0eeb2b7036923ef9a6e0 (diff) | |
download | frameworks_base-1e650e26a7bb2f02635530a46ecd715f9911d40e.zip frameworks_base-1e650e26a7bb2f02635530a46ecd715f9911d40e.tar.gz frameworks_base-1e650e26a7bb2f02635530a46ecd715f9911d40e.tar.bz2 |
Merge "New floating toolbar implementation for secondary action mode views."
-rw-r--r-- | core/java/com/android/internal/widget/FloatingToolbar.java | 596 | ||||
-rw-r--r-- | core/res/res/layout/floating_popup_container.xml | 25 | ||||
-rw-r--r-- | core/res/res/layout/floating_popup_menu_button.xml | 31 | ||||
-rw-r--r-- | core/res/res/layout/floating_popup_open_overflow_button.xml | 25 | ||||
-rw-r--r-- | core/res/res/values/dimens.xml | 7 | ||||
-rwxr-xr-x | core/res/res/values/symbols.xml | 11 |
6 files changed, 695 insertions, 0 deletions
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java new file mode 100644 index 0000000..be9945d --- /dev/null +++ b/core/java/com/android/internal/widget/FloatingToolbar.java @@ -0,0 +1,596 @@ +/* + * 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.internal.widget; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.content.Context; +import android.graphics.Color; +import android.graphics.Point; +import android.graphics.Rect; +import android.graphics.drawable.ColorDrawable; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.View.MeasureSpec; +import android.view.ViewGroup; +import android.view.Window; +import android.widget.Button; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.PopupWindow; + +import com.android.internal.R; +import com.android.internal.util.Preconditions; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * A floating toolbar for showing contextual menu items. + * This view shows as many menu item buttons as can fit in the horizontal toolbar and the + * the remaining menu items in a vertical overflow view when the overflow button is clicked. + * The horizontal toolbar morphs into the vertical overflow view. + */ +public final class FloatingToolbar { + + private static final MenuItem.OnMenuItemClickListener NO_OP_MENUITEM_CLICK_LISTENER = + new MenuItem.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + return false; + } + }; + + private final Context mContext; + private final FloatingToolbarPopup mPopup; + private final ViewGroup mMenuItemButtonsContainer; + private final View.OnClickListener mMenuItemButtonOnClickListener = + new View.OnClickListener() { + @Override + public void onClick(View v) { + if (v.getTag() instanceof MenuItem) { + mMenuItemClickListener.onMenuItemClick((MenuItem) v.getTag()); + mPopup.dismiss(); + } + } + }; + + private final Rect mContentRect = new Rect(); + private final Point mCoordinates = new Point(); + + private Menu mMenu; + private List<CharSequence> mShowingTitles = new ArrayList<CharSequence>(); + private MenuItem.OnMenuItemClickListener mMenuItemClickListener = NO_OP_MENUITEM_CLICK_LISTENER; + private View mOpenOverflowButton; + + private int mSuggestedWidth; + + /** + * Initializes a floating toolbar. + */ + public FloatingToolbar(Context context, Window window) { + mContext = Preconditions.checkNotNull(context); + mPopup = new FloatingToolbarPopup(Preconditions.checkNotNull(window.getDecorView())); + mMenuItemButtonsContainer = createMenuButtonsContainer(context); + } + + /** + * Sets the menu to be shown in this floating toolbar. + * NOTE: Call {@link #updateLayout()} or {@link #show()} to effect visual changes to the + * toolbar. + */ + public FloatingToolbar setMenu(Menu menu) { + mMenu = Preconditions.checkNotNull(menu); + return this; + } + + /** + * Sets the custom listener for invocation of menu items in this floating + * toolbar. + */ + public FloatingToolbar setOnMenuItemClickListener( + MenuItem.OnMenuItemClickListener menuItemClickListener) { + if (menuItemClickListener != null) { + mMenuItemClickListener = menuItemClickListener; + } else { + mMenuItemClickListener = NO_OP_MENUITEM_CLICK_LISTENER; + } + return this; + } + + /** + * Sets the content rectangle. This is the area of the interesting content that this toolbar + * should avoid obstructing. + * NOTE: Call {@link #updateLayout()} or {@link #show()} to effect visual changes to the + * toolbar. + */ + public FloatingToolbar setContentRect(Rect rect) { + mContentRect.set(Preconditions.checkNotNull(rect)); + return this; + } + + /** + * Sets the suggested width of this floating toolbar. + * The actual width will be about this size but there are no guarantees that it will be exactly + * the suggested width. + * NOTE: Call {@link #updateLayout()} or {@link #show()} to effect visual changes to the + * toolbar. + */ + public FloatingToolbar setSuggestedWidth(int suggestedWidth) { + mSuggestedWidth = suggestedWidth; + return this; + } + + /** + * Shows this floating toolbar. + */ + public FloatingToolbar show() { + List<MenuItem> menuItems = getVisibleAndEnabledMenuItems(mMenu); + if (hasContentChanged(menuItems) || hasWidthChanged()) { + mPopup.dismiss(); + layoutMenuItemButtons(menuItems); + mShowingTitles = getMenuItemTitles(menuItems); + } + refreshCoordinates(); + mPopup.updateCoordinates(mCoordinates.x, mCoordinates.y); + if (!mPopup.isShowing()) { + mPopup.show(mCoordinates.x, mCoordinates.y); + } + return this; + } + + /** + * Updates this floating toolbar to reflect recent position and view updates. + * NOTE: This method is a no-op if the toolbar isn't showing. + */ + public FloatingToolbar updateLayout() { + if (mPopup.isShowing()) { + // show() performs all the logic we need here. + show(); + } + return this; + } + + /** + * Dismisses this floating toolbar. + */ + public void dismiss() { + mPopup.dismiss(); + } + + /** + * Returns {@code true} if this popup is currently showing. {@code false} otherwise. + */ + public boolean isShowing() { + return mPopup.isShowing(); + } + + /** + * Refreshes {@link #mCoordinates} with values based on {@link #mContentRect}. + */ + private void refreshCoordinates() { + int popupWidth = mPopup.getWidth(); + int popupHeight = mPopup.getHeight(); + if (!mPopup.isShowing()) { + // Popup isn't yet shown, get estimated size from the menu item buttons container. + mMenuItemButtonsContainer.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); + popupWidth = mMenuItemButtonsContainer.getMeasuredWidth(); + popupHeight = mMenuItemButtonsContainer.getMeasuredHeight(); + } + int x = mContentRect.centerX() - popupWidth / 2; + int y; + if (shouldDisplayAtTopOfContent()) { + y = mContentRect.top - popupHeight; + } else { + y = mContentRect.bottom; + } + mCoordinates.set(x, y); + } + + /** + * Returns true if this floating toolbar's menu items have been reordered or changed. + */ + private boolean hasContentChanged(List<MenuItem> menuItems) { + return !mShowingTitles.equals(getMenuItemTitles(menuItems)); + } + + /** + * Returns true if there is a significant change in width of the toolbar. + */ + private boolean hasWidthChanged() { + int actualWidth = mPopup.getWidth(); + int difference = Math.abs(actualWidth - mSuggestedWidth); + return difference > (actualWidth * 0.2); + } + + /** + * Returns true if the preferred positioning of the toolbar is above the content rect. + */ + private boolean shouldDisplayAtTopOfContent() { + return mContentRect.top - getMinimumOverflowHeight(mContext) > 0; + } + + /** + * Returns the visible and enabled menu items in the specified menu. + * This method is recursive. + */ + private List<MenuItem> getVisibleAndEnabledMenuItems(Menu menu) { + List<MenuItem> menuItems = new ArrayList<MenuItem>(); + for (int i = 0; (menu != null) && (i < menu.size()); i++) { + MenuItem menuItem = menu.getItem(i); + if (menuItem.isVisible() && menuItem.isEnabled()) { + Menu subMenu = menuItem.getSubMenu(); + if (subMenu != null) { + menuItems.addAll(getVisibleAndEnabledMenuItems(subMenu)); + } else { + menuItems.add(menuItem); + } + } + } + return menuItems; + } + + private List<CharSequence> getMenuItemTitles(List<MenuItem> menuItems) { + List<CharSequence> titles = new ArrayList<CharSequence>(); + for (MenuItem menuItem : menuItems) { + titles.add(menuItem.getTitle()); + } + return titles; + } + + private void layoutMenuItemButtons(List<MenuItem> menuItems) { + final int toolbarWidth = getAdjustedToolbarWidth(mContext, mSuggestedWidth) + // Reserve space for the "open overflow" button. + - getEstimatedOpenOverflowButtonWidth(mContext); + + int availableWidth = toolbarWidth; + LinkedList<MenuItem> remainingMenuItems = new LinkedList<MenuItem>(menuItems); + + mMenuItemButtonsContainer.removeAllViews(); + + boolean isFirstItem = true; + while (!remainingMenuItems.isEmpty()) { + final MenuItem menuItem = remainingMenuItems.peek(); + Button menuItemButton = createMenuItemButton(mContext, menuItem); + + // Adding additional left padding for the first button to even out button spacing. + if (isFirstItem) { + menuItemButton.setPadding( + 2 * menuItemButton.getPaddingLeft(), + menuItemButton.getPaddingTop(), + menuItemButton.getPaddingRight(), + menuItemButton.getPaddingBottom()); + isFirstItem = false; + } + + // Adding additional right padding for the last button to even out button spacing. + if (remainingMenuItems.size() == 1) { + menuItemButton.setPadding( + menuItemButton.getPaddingLeft(), + menuItemButton.getPaddingTop(), + 2 * menuItemButton.getPaddingRight(), + menuItemButton.getPaddingBottom()); + } + + menuItemButton.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); + int menuItemButtonWidth = Math.min(menuItemButton.getMeasuredWidth(), toolbarWidth); + if (menuItemButtonWidth <= availableWidth) { + menuItemButton.setTag(menuItem); + menuItemButton.setOnClickListener(mMenuItemButtonOnClickListener); + mMenuItemButtonsContainer.addView(menuItemButton); + menuItemButton.getLayoutParams().width = menuItemButtonWidth; + availableWidth -= menuItemButtonWidth; + remainingMenuItems.pop(); + } else { + // The "open overflow" button launches the vertical overflow from the + // floating toolbar. + createOpenOverflowButtonIfNotExists(); + mMenuItemButtonsContainer.addView(mOpenOverflowButton); + break; + } + } + mPopup.setContentView(mMenuItemButtonsContainer); + } + + /** + * Creates and returns the button that opens the vertical overflow. + */ + private void createOpenOverflowButtonIfNotExists() { + mOpenOverflowButton = (ImageButton) LayoutInflater.from(mContext) + .inflate(R.layout.floating_popup_open_overflow_button, null); + mOpenOverflowButton.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + // Open the overflow. + } + }); + } + + /** + * Creates and returns a floating toolbar menu buttons container. + */ + private static ViewGroup createMenuButtonsContainer(Context context) { + return (ViewGroup) LayoutInflater.from(context) + .inflate(R.layout.floating_popup_container, null); + } + + /** + * Creates and returns a menu button for the specified menu item. + */ + private static Button createMenuItemButton(Context context, MenuItem menuItem) { + Button menuItemButton = (Button) LayoutInflater.from(context) + .inflate(R.layout.floating_popup_menu_button, null); + menuItemButton.setText(menuItem.getTitle()); + menuItemButton.setContentDescription(menuItem.getTitle()); + return menuItemButton; + } + + private static int getMinimumOverflowHeight(Context context) { + return context.getResources(). + getDimensionPixelSize(R.dimen.floating_toolbar_minimum_overflow_height); + } + + private static int getEstimatedOpenOverflowButtonWidth(Context context) { + return context.getResources() + .getDimensionPixelSize(R.dimen.floating_toolbar_menu_button_minimum_width); + } + + private static int getAdjustedToolbarWidth(Context context, int width) { + if (width <= 0 || width > getScreenWidth(context)) { + width = context.getResources() + .getDimensionPixelSize(R.dimen.floating_toolbar_default_width); + } + return width; + } + + /** + * Returns the device's screen width. + */ + public static int getScreenWidth(Context context) { + return context.getResources().getDisplayMetrics().widthPixels; + } + + /** + * Returns the device's screen height. + */ + public static int getScreenHeight(Context context) { + return context.getResources().getDisplayMetrics().heightPixels; + } + + + /** + * A popup window used by the floating toolbar. + */ + private static final class FloatingToolbarPopup { + + private final View mParent; + private final PopupWindow mPopupWindow; + private final ViewGroup mContentContainer; + private final Animator.AnimatorListener mOnDismissEnd = + new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mPopupWindow.dismiss(); + mDismissAnimating = false; + } + }; + private final AnimatorSet mGrowFadeInFromBottomAnimation; + private final AnimatorSet mShrinkFadeOutFromBottomAnimation; + + private boolean mDismissAnimating; + + /** + * Initializes a new floating bar popup. + * + * @param parent A parent view to get the {@link View#getWindowToken()} token from. + */ + public FloatingToolbarPopup(View parent) { + mParent = Preconditions.checkNotNull(parent); + mContentContainer = createContentContainer(parent.getContext()); + mPopupWindow = createPopupWindow(mContentContainer); + mGrowFadeInFromBottomAnimation = createGrowFadeInFromBottom(mContentContainer); + mShrinkFadeOutFromBottomAnimation = + createShrinkFadeOutFromBottomAnimation(mContentContainer, mOnDismissEnd); + } + + /** + * Shows this popup at the specified coordinates. + * The specified coordinates may be adjusted to make sure the popup is entirely on-screen. + * If this popup is already showing, this will be a no-op. + */ + public void show(int x, int y) { + if (isShowing()) { + updateCoordinates(x, y); + return; + } + + mPopupWindow.showAtLocation(mParent, Gravity.NO_GRAVITY, 0, 0); + positionOnScreen(x, y); + growFadeInFromBottom(); + + mDismissAnimating = false; + } + + /** + * Gets rid of this popup. If the popup isn't currently showing, this will be a no-op. + */ + public void dismiss() { + if (!isShowing()) { + return; + } + + if (mDismissAnimating) { + // This window is already dismissing. Don't restart the animation. + return; + } + mDismissAnimating = true; + shrinkFadeOutFromBottom(); + } + + /** + * Returns {@code true} if this popup is currently showing. {@code false} otherwise. + */ + public boolean isShowing() { + return mPopupWindow.isShowing() && !mDismissAnimating; + } + + /** + * Updates the coordinates of this popup. + * The specified coordinates may be adjusted to make sure the popup is entirely on-screen. + */ + public void updateCoordinates(int x, int y) { + if (isShowing()) { + positionOnScreen(x, y); + } + } + + /** + * Sets the content of this popup. + */ + public void setContentView(View view) { + Preconditions.checkNotNull(view); + mContentContainer.removeAllViews(); + mContentContainer.addView(view); + } + + /** + * Returns the width of this popup. + */ + public int getWidth() { + return mContentContainer.getWidth(); + } + + /** + * Returns the height of this popup. + */ + public int getHeight() { + return mContentContainer.getHeight(); + } + + /** + * Returns the context this popup is running in. + */ + public Context getContext() { + return mContentContainer.getContext(); + } + + private void positionOnScreen(int x, int y) { + if (getWidth() == 0) { + // content size is yet to be measured. + mContentContainer.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); + } + x = clamp(x, 0, getScreenWidth(getContext()) - getWidth()); + y = clamp(y, 0, getScreenHeight(getContext()) - getHeight()); + + // Position the view w.r.t. the window. + mContentContainer.setX(x); + mContentContainer.setY(y); + } + + /** + * Performs the "grow and fade in from the bottom" animation on the floating popup. + */ + private void growFadeInFromBottom() { + setPivot(); + mGrowFadeInFromBottomAnimation.start(); + } + + /** + * Performs the "shrink and fade out from bottom" animation on the floating popup. + */ + private void shrinkFadeOutFromBottom() { + setPivot(); + mShrinkFadeOutFromBottomAnimation.start(); + } + + /** + * Sets the popup content container's pivot. + */ + private void setPivot() { + mContentContainer.setPivotX(mContentContainer.getMeasuredWidth() / 2); + mContentContainer.setPivotY(mContentContainer.getMeasuredHeight()); + } + + private static ViewGroup createContentContainer(Context context) { + return (ViewGroup) LayoutInflater.from(context) + .inflate(R.layout.floating_popup_container, null); + } + + private static PopupWindow createPopupWindow(View content) { + ViewGroup popupContentHolder = new LinearLayout(content.getContext()); + PopupWindow popupWindow = new PopupWindow(popupContentHolder); + popupWindow.setAnimationStyle(0); + popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + popupWindow.setWidth(getScreenWidth(content.getContext())); + popupWindow.setHeight(getScreenHeight(content.getContext())); + content.setLayoutParams(new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + popupContentHolder.addView(content); + return popupWindow; + } + + /** + * Creates a "grow and fade in from the bottom" animation for the specified view. + * + * @param view The view to animate + */ + private static AnimatorSet createGrowFadeInFromBottom(View view) { + AnimatorSet growFadeInFromBottomAnimation = new AnimatorSet(); + growFadeInFromBottomAnimation.playTogether( + ObjectAnimator.ofFloat(view, View.SCALE_X, 0.5f, 1).setDuration(125), + ObjectAnimator.ofFloat(view, View.SCALE_Y, 0.5f, 1).setDuration(125), + ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1).setDuration(75)); + return growFadeInFromBottomAnimation; + } + + /** + * Creates a "shrink and fade out from bottom" animation for the specified view. + * + * @param view The view to animate + * @param listener The animation listener + */ + private static AnimatorSet createShrinkFadeOutFromBottomAnimation( + View view, Animator.AnimatorListener listener) { + AnimatorSet shrinkFadeOutFromBottomAnimation = new AnimatorSet(); + shrinkFadeOutFromBottomAnimation.playTogether( + ObjectAnimator.ofFloat(view, View.SCALE_Y, 1, 0.5f).setDuration(125), + ObjectAnimator.ofFloat(view, View.ALPHA, 1, 0).setDuration(75)); + shrinkFadeOutFromBottomAnimation.setStartDelay(150); + shrinkFadeOutFromBottomAnimation.addListener(listener); + return shrinkFadeOutFromBottomAnimation; + } + + /** + * Returns value, restricted to the range min->max (inclusive). + * If maximum is less than minimum, the result is undefined. + * + * @param value The value to clamp. + * @param minimum The minimum value in the range. + * @param maximum The maximum value in the range. Must not be less than minimum. + */ + private static int clamp(int value, int minimum, int maximum) { + return Math.max(minimum, Math.min(value, maximum)); + } + } +} diff --git a/core/res/res/layout/floating_popup_container.xml b/core/res/res/layout/floating_popup_container.xml new file mode 100644 index 0000000..f247919 --- /dev/null +++ b/core/res/res/layout/floating_popup_container.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* Copyright 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. +*/ +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="horizontal" + android:layout_width="wrap_content" + android:layout_height="@dimen/floating_toolbar_height" + android:elevation="2dp" + android:focusable="true" + android:focusableInTouchMode="true" + android:background="@android:color/background_light" /> diff --git a/core/res/res/layout/floating_popup_menu_button.xml b/core/res/res/layout/floating_popup_menu_button.xml new file mode 100644 index 0000000..9fa13bd --- /dev/null +++ b/core/res/res/layout/floating_popup_menu_button.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* Copyright 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. +*/ +--> +<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:paddingLeft="@dimen/floating_toolbar_menu_button_side_padding" + android:paddingRight="@dimen/floating_toolbar_menu_button_side_padding" + android:paddingTop="0dp" + android:paddingBottom="0dp" + android:singleLine="true" + android:ellipsize="end" + android:fontFamily="sans-serif" + android:textSize="@dimen/floating_toolbar_text_size" + android:textAllCaps="true" + android:background="?attr/selectableItemBackground" />
\ No newline at end of file diff --git a/core/res/res/layout/floating_popup_open_overflow_button.xml b/core/res/res/layout/floating_popup_open_overflow_button.xml new file mode 100644 index 0000000..4c1176c --- /dev/null +++ b/core/res/res/layout/floating_popup_open_overflow_button.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* Copyright 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. +*/ +--> +<ImageButton xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="@dimen/floating_toolbar_menu_button_minimum_width" + android:layout_height="match_parent" + android:minWidth="@dimen/floating_toolbar_menu_button_minimum_width" + android:minHeight="@dimen/floating_toolbar_height" + android:src="@drawable/ic_menu_moreoverflow_material" + android:contentDescription="@string/action_menu_overflow_description" + android:background="?attr/selectableItemBackgroundBorderless" /> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 6c6d2cc..3431f35 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -386,4 +386,11 @@ <item type="dimen" format="float" name="ambient_shadow_alpha">0.075</item> <item type="dimen" format="float" name="spot_shadow_alpha">0.15</item> + <!-- Floating toolbar dimensions --> + <dimen name="floating_toolbar_height">48dp</dimen> + <dimen name="floating_toolbar_menu_button_side_padding">8dp</dimen> + <dimen name="floating_toolbar_text_size">14sp</dimen> + <dimen name="floating_toolbar_menu_button_minimum_width">48dp</dimen> + <dimen name="floating_toolbar_default_width">250dp</dimen> + <dimen name="floating_toolbar_minimum_overflow_height">192dp</dimen> </resources> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index fcf9ff4..67d5472 100755 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2194,4 +2194,15 @@ <java-symbol type="dimen" name="date_picker_day_of_week_height"/> <java-symbol type="id" name="accessibility_action_show_on_screen" /> + + <!-- Floating toolbar --> + <java-symbol type="layout" name="floating_popup_container" /> + <java-symbol type="layout" name="floating_popup_menu_button" /> + <java-symbol type="layout" name="floating_popup_open_overflow_button" /> + <java-symbol type="dimen" name="floating_toolbar_height" /> + <java-symbol type="dimen" name="floating_toolbar_menu_button_side_padding" /> + <java-symbol type="dimen" name="floating_toolbar_text_size" /> + <java-symbol type="dimen" name="floating_toolbar_menu_button_minimum_width" /> + <java-symbol type="dimen" name="floating_toolbar_default_width" /> + <java-symbol type="dimen" name="floating_toolbar_minimum_overflow_height" /> </resources> |