Commit 77054ce5 authored by dtrainor@chromium.org's avatar dtrainor@chromium.org

Update Android menu to overlap anchor

- Fix menu bg asset to properly allow the menu to overlap the anchor
- Turn on dismiss button in menu
- Fix some animation code related to the dismiss button in the menu
- Make overlapping an RTL item work properly

BUG=394898
NOTRY=true

Review URL: https://codereview.chromium.org/419673002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@285728 0039d316-1c4b-4281-b951-d872f2087c98
parent 4657e610
...@@ -10,7 +10,8 @@ ...@@ -10,7 +10,8 @@
android:toXScale="1" android:toXScale="1"
android:fromYScale="0" android:fromYScale="0"
android:toYScale="1" android:toYScale="1"
android:pivotX="95%" android:pivotY="5%" android:pivotX="@fraction/menu_animation_pivot_x"
android:pivotY="5%"
android:duration="200" /> android:duration="200" />
<alpha android:interpolator="@android:anim/linear_interpolator" <alpha android:interpolator="@android:anim/linear_interpolator"
android:fromAlpha="0" android:toAlpha="1" android:fromAlpha="0" android:toAlpha="1"
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
android:toXScale="0.5" android:toXScale="0.5"
android:fromYScale="1" android:fromYScale="1"
android:toYScale="0.5" android:toYScale="0.5"
android:pivotX="95%" android:pivotX="@fraction/menu_animation_pivot_x"
android:pivotY="5%" android:pivotY="5%"
android:duration="150" /> android:duration="150" />
<alpha android:interpolator="@interpolator/fade_out_curve_interpolator" <alpha android:interpolator="@interpolator/fade_out_curve_interpolator"
......
...@@ -43,5 +43,4 @@ ...@@ -43,5 +43,4 @@
android:paddingStart="11dp" android:paddingStart="11dp"
android:background="?android:attr/listChoiceBackgroundIndicator" android:background="?android:attr/listChoiceBackgroundIndicator"
android:scaleType="center" /> android:scaleType="center" />
</LinearLayout> </LinearLayout>
\ No newline at end of file
...@@ -27,5 +27,5 @@ ...@@ -27,5 +27,5 @@
android:background="?android:attr/listChoiceBackgroundIndicator" android:background="?android:attr/listChoiceBackgroundIndicator"
android:padding="10dp" android:padding="10dp"
android:scaleType="fitCenter" /> android:scaleType="fitCenter" />
</LinearLayout> </LinearLayout>
\ No newline at end of file
...@@ -3,10 +3,7 @@ ...@@ -3,10 +3,7 @@
Use of this source code is governed by a BSD-style license that can be Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. found in the LICENSE file.
--> -->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<resources> <!-- Menu Animation Constants -->
<!-- Menu Dimensions --> <item type="fraction" format="fraction" name="menu_animation_pivot_x">5%</item>
<!-- Necessary to align the menu with the bottom of the toolbar (the anchored button does not </resources>
extend to the bottom of the toolbar). --> \ No newline at end of file
<dimen name="menu_vertical_offset">2dp</dimen>
</resources>
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
<item name="android:listPreferredItemPaddingStart">16dp</item> <item name="android:listPreferredItemPaddingStart">16dp</item>
<item name="android:listPreferredItemPaddingEnd">16dp</item> <item name="android:listPreferredItemPaddingEnd">16dp</item>
<item name="android:textSize">16sp</item> <item name="android:textSize">16sp</item>
<item name="android:popupAnimationStyle">@style/OverflowMenuAnim</item>
</style> </style>
<style name="OverflowMenuAnim"> <style name="OverflowMenuAnim">
<item name="android:windowEnterAnimation">@anim/menu_enter</item> <item name="android:windowEnterAnimation">@anim/menu_enter</item>
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
<!-- Custom Menu dimensions --> <!-- Custom Menu dimensions -->
<dimen name="menu_width">258dp</dimen> <dimen name="menu_width">258dp</dimen>
<dimen name="menu_vertical_offset">0dp</dimen>
<!-- The amount to fade the edges of the menu to indicate more content is available <!-- The amount to fade the edges of the menu to indicate more content is available
via scrolling. --> via scrolling. -->
<dimen name="menu_vertical_fade_distance">15dp</dimen> <dimen name="menu_vertical_fade_distance">15dp</dimen>
......
...@@ -11,4 +11,7 @@ ...@@ -11,4 +11,7 @@
<item type="id" name="button_secondary" /> <item type="id" name="button_secondary" />
<item type="id" name="button_tertiary" /> <item type="id" name="button_tertiary" />
<item type="id" name="infobar_extra_check" /> <item type="id" name="infobar_extra_check" />
<!-- Menu Animation Constants -->
<item type="fraction" format="fraction" name="menu_animation_pivot_x">95%</item>
</resources> </resources>
...@@ -37,7 +37,7 @@ import java.util.List; ...@@ -37,7 +37,7 @@ import java.util.List;
*/ */
public class AppMenu implements OnItemClickListener, OnKeyListener { public class AppMenu implements OnItemClickListener, OnKeyListener {
/** Whether or not to show the software menu button in the menu. */ /** Whether or not to show the software menu button in the menu. */
private static final boolean SHOW_SW_MENU_BUTTON = false; private static final boolean SHOW_SW_MENU_BUTTON = true;
private static final float LAST_ITEM_SHOW_FRACTION = 0.5f; private static final float LAST_ITEM_SHOW_FRACTION = 0.5f;
...@@ -45,7 +45,6 @@ public class AppMenu implements OnItemClickListener, OnKeyListener { ...@@ -45,7 +45,6 @@ public class AppMenu implements OnItemClickListener, OnKeyListener {
private final int mItemRowHeight; private final int mItemRowHeight;
private final int mItemDividerHeight; private final int mItemDividerHeight;
private final int mVerticalFadeDistance; private final int mVerticalFadeDistance;
private final int mAdditionalVerticalOffset;
private ListPopupWindow mPopup; private ListPopupWindow mPopup;
private AppMenuAdapter mAdapter; private AppMenuAdapter mAdapter;
private AppMenuHandler mHandler; private AppMenuHandler mHandler;
...@@ -72,7 +71,6 @@ public class AppMenu implements OnItemClickListener, OnKeyListener { ...@@ -72,7 +71,6 @@ public class AppMenu implements OnItemClickListener, OnKeyListener {
mItemDividerHeight = itemDividerHeight; mItemDividerHeight = itemDividerHeight;
assert mItemDividerHeight >= 0; assert mItemDividerHeight >= 0;
mAdditionalVerticalOffset = res.getDimensionPixelSize(R.dimen.menu_vertical_offset);
mVerticalFadeDistance = res.getDimensionPixelSize(R.dimen.menu_vertical_fade_distance); mVerticalFadeDistance = res.getDimensionPixelSize(R.dimen.menu_vertical_fade_distance);
} }
...@@ -105,7 +103,13 @@ public class AppMenu implements OnItemClickListener, OnKeyListener { ...@@ -105,7 +103,13 @@ public class AppMenu implements OnItemClickListener, OnKeyListener {
// Need to explicitly set the background here. Relying on it being set in the style caused // Need to explicitly set the background here. Relying on it being set in the style caused
// an incorrectly drawn background. // an incorrectly drawn background.
mPopup.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.menu_bg)); if (isByHardwareButton) {
mPopup.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.menu_bg));
} else {
mPopup.setBackgroundDrawable(
context.getResources().getDrawable(R.drawable.edge_menu_bg));
mPopup.setAnimationStyle(R.style.OverflowMenuAnim);
}
Rect bgPadding = new Rect(); Rect bgPadding = new Rect();
mPopup.getBackground().getPadding(bgPadding); mPopup.getBackground().getPadding(bgPadding);
...@@ -165,6 +169,7 @@ public class AppMenu implements OnItemClickListener, OnKeyListener { ...@@ -165,6 +169,7 @@ public class AppMenu implements OnItemClickListener, OnKeyListener {
popup.getBackground().getPadding(paddingRect); popup.getBackground().getPadding(paddingRect);
int[] anchorLocation = new int[2]; int[] anchorLocation = new int[2];
popup.getAnchorView().getLocationInWindow(anchorLocation); popup.getAnchorView().getLocationInWindow(anchorLocation);
int anchorHeight = popup.getAnchorView().getHeight();
// If we have a hardware menu button, locate the app menu closer to the estimated // If we have a hardware menu button, locate the app menu closer to the estimated
// hardware menu button location. // hardware menu button location.
...@@ -187,11 +192,11 @@ public class AppMenu implements OnItemClickListener, OnKeyListener { ...@@ -187,11 +192,11 @@ public class AppMenu implements OnItemClickListener, OnKeyListener {
popup.setHorizontalOffset(horizontalOffset); popup.setHorizontalOffset(horizontalOffset);
// The menu is displayed above the anchored view, so shift the menu up by the top // The menu is displayed above the anchored view, so shift the menu up by the top
// padding of the background. // padding of the background.
popup.setVerticalOffset(mAdditionalVerticalOffset - paddingRect.bottom); popup.setVerticalOffset(-paddingRect.bottom);
} else { } else {
// The menu is displayed below the anchored view, so shift the menu up by the top // The menu is displayed over and below the anchored view, so shift the menu up by the
// padding of the background. // height of the anchor view.
popup.setVerticalOffset(mAdditionalVerticalOffset - paddingRect.top); popup.setVerticalOffset(-anchorHeight);
} }
} }
...@@ -264,9 +269,10 @@ public class AppMenu implements OnItemClickListener, OnKeyListener { ...@@ -264,9 +269,10 @@ public class AppMenu implements OnItemClickListener, OnKeyListener {
int[] anchorViewLocation = new int[2]; int[] anchorViewLocation = new int[2];
anchorView.getLocationOnScreen(anchorViewLocation); anchorView.getLocationOnScreen(anchorViewLocation);
anchorViewLocation[1] -= appDimensions.top; anchorViewLocation[1] -= appDimensions.top;
int anchorViewImpactHeight = mIsByHardwareButton ? anchorView.getHeight() : 0;
int availableScreenSpace = Math.max(anchorViewLocation[1], int availableScreenSpace = Math.max(anchorViewLocation[1],
appDimensions.height() - anchorViewLocation[1] - anchorView.getHeight()); appDimensions.height() - anchorViewLocation[1] - anchorViewImpactHeight);
Rect padding = new Rect(); Rect padding = new Rect();
mPopup.getBackground().getPadding(padding); mPopup.getBackground().getPadding(padding);
......
...@@ -17,10 +17,13 @@ import android.view.ViewGroup; ...@@ -17,10 +17,13 @@ import android.view.ViewGroup;
import android.widget.BaseAdapter; import android.widget.BaseAdapter;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.ListView; import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.ui.base.LocalizationUtils;
import org.chromium.ui.interpolators.BakedBezierInterpolator; import org.chromium.ui.interpolators.BakedBezierInterpolator;
import java.util.List; import java.util.List;
...@@ -29,7 +32,7 @@ import java.util.List; ...@@ -29,7 +32,7 @@ import java.util.List;
* ListAdapter to customize the view of items in the list. * ListAdapter to customize the view of items in the list.
*/ */
class AppMenuAdapter extends BaseAdapter { class AppMenuAdapter extends BaseAdapter {
private static final int VIEW_TYPE_COUNT = 4; private static final int VIEW_TYPE_COUNT = 5;
/** /**
* Regular Android menu item that contains a title and an icon if icon is specified. * Regular Android menu item that contains a title and an icon if icon is specified.
...@@ -48,6 +51,11 @@ class AppMenuAdapter extends BaseAdapter { ...@@ -48,6 +51,11 @@ class AppMenuAdapter extends BaseAdapter {
* Menu item that has four buttons. Every one of these buttons is displayed as an icon. * Menu item that has four buttons. Every one of these buttons is displayed as an icon.
*/ */
private static final int FOUR_BUTTON_MENU_ITEM = 3; private static final int FOUR_BUTTON_MENU_ITEM = 3;
/**
* Menu item that has two buttons, the first one is a title and the second is a menu icon.
* This is similar to {@link #TITLE_BUTTON_MENU_ITEM} but has some slight layout differences.
*/
private static final int MENU_BUTTON_MENU_ITEM = 4;
/** MenuItem Animation Constants */ /** MenuItem Animation Constants */
private static final int ENTER_ITEM_DURATION_MS = 350; private static final int ENTER_ITEM_DURATION_MS = 350;
...@@ -56,6 +64,10 @@ class AppMenuAdapter extends BaseAdapter { ...@@ -56,6 +64,10 @@ class AppMenuAdapter extends BaseAdapter {
private static final float ENTER_STANDARD_ITEM_OFFSET_Y_DP = -10.f; private static final float ENTER_STANDARD_ITEM_OFFSET_Y_DP = -10.f;
private static final float ENTER_STANDARD_ITEM_OFFSET_X_DP = 10.f; private static final float ENTER_STANDARD_ITEM_OFFSET_X_DP = 10.f;
/** Menu Button Layout Constants */
private static final float MENU_BUTTON_WIDTH_DP = 59.f;
private static final float MENU_BUTTON_START_PADDING_DP = 19.f;
private final AppMenu mAppMenu; private final AppMenu mAppMenu;
private final LayoutInflater mInflater; private final LayoutInflater mInflater;
private final List<MenuItem> mMenuItems; private final List<MenuItem> mMenuItems;
...@@ -86,15 +98,16 @@ class AppMenuAdapter extends BaseAdapter { ...@@ -86,15 +98,16 @@ class AppMenuAdapter extends BaseAdapter {
@Override @Override
public int getItemViewType(int position) { public int getItemViewType(int position) {
MenuItem item = getItem(position); MenuItem item = getItem(position);
boolean hasMenuButton = mShowMenuButton && position == 0;
int viewCount = item.hasSubMenu() ? item.getSubMenu().size() : 1; int viewCount = item.hasSubMenu() ? item.getSubMenu().size() : 1;
if (mShowMenuButton && position == 0) viewCount++; if (hasMenuButton) viewCount++;
if (viewCount == 4) { if (viewCount == 4) {
return FOUR_BUTTON_MENU_ITEM; return FOUR_BUTTON_MENU_ITEM;
} else if (viewCount == 3) { } else if (viewCount == 3) {
return THREE_BUTTON_MENU_ITEM; return THREE_BUTTON_MENU_ITEM;
} else if (viewCount == 2) { } else if (viewCount == 2) {
return TITLE_BUTTON_MENU_ITEM; return hasMenuButton ? MENU_BUTTON_MENU_ITEM : TITLE_BUTTON_MENU_ITEM;
} }
return STANDARD_MENU_ITEM; return STANDARD_MENU_ITEM;
} }
...@@ -204,16 +217,21 @@ class AppMenuAdapter extends BaseAdapter { ...@@ -204,16 +217,21 @@ class AppMenuAdapter extends BaseAdapter {
convertView.setEnabled(false); convertView.setEnabled(false);
break; break;
} }
case TITLE_BUTTON_MENU_ITEM: { case TITLE_BUTTON_MENU_ITEM:
// Fall through.
case MENU_BUTTON_MENU_ITEM: {
TitleButtonMenuItemViewHolder holder = null; TitleButtonMenuItemViewHolder holder = null;
if (convertView == null) { if (convertView == null) {
holder = new TitleButtonMenuItemViewHolder(); holder = new TitleButtonMenuItemViewHolder();
convertView = mInflater.inflate(R.layout.title_button_menu_item, parent, false); convertView = mInflater.inflate(R.layout.title_button_menu_item, parent, false);
holder.title = (TextView) convertView.findViewById(R.id.title); holder.title = (TextView) convertView.findViewById(R.id.title);
holder.button = (ImageButton) convertView.findViewById(R.id.button); holder.button = (ImageButton) convertView.findViewById(R.id.button);
View animatedView = hasMenuButton ? holder.title : convertView;
convertView.setTag(holder); convertView.setTag(holder);
convertView.setTag(R.id.menu_item_enter_anim_id, convertView.setTag(R.id.menu_item_enter_anim_id,
buildStandardItemEnterAnimator(convertView, position)); buildStandardItemEnterAnimator(animatedView, position));
} else { } else {
holder = (TitleButtonMenuItemViewHolder) convertView.getTag(); holder = (TitleButtonMenuItemViewHolder) convertView.getTag();
} }
...@@ -275,6 +293,12 @@ class AppMenuAdapter extends BaseAdapter { ...@@ -275,6 +293,12 @@ class AppMenuAdapter extends BaseAdapter {
mAppMenu.dismiss(); mAppMenu.dismiss();
} }
}); });
// Set the button layout to make it properly line up with any underlying menu button
ApiCompatibilityUtils.setPaddingRelative(
button, (int) (MENU_BUTTON_START_PADDING_DP * mDpToPx), 0, 0, 0);
button.getLayoutParams().width = (int) (MENU_BUTTON_WIDTH_DP * mDpToPx);
button.setScaleType(ScaleType.CENTER);
} }
/** /**
...@@ -315,7 +339,8 @@ class AppMenuAdapter extends BaseAdapter { ...@@ -315,7 +339,8 @@ class AppMenuAdapter extends BaseAdapter {
* @return The {@link Animator}. * @return The {@link Animator}.
*/ */
private Animator buildIconItemEnterAnimator(final ImageView[] views, boolean skipLastItem) { private Animator buildIconItemEnterAnimator(final ImageView[] views, boolean skipLastItem) {
final float offsetXPx = ENTER_STANDARD_ITEM_OFFSET_X_DP * mDpToPx; final boolean rtl = LocalizationUtils.isLayoutRtl();
final float offsetXPx = ENTER_STANDARD_ITEM_OFFSET_X_DP * mDpToPx * (rtl ? -1.f : 1.f);
final int maxViewsToAnimate = views.length - (skipLastItem ? 1 : 0); final int maxViewsToAnimate = views.length - (skipLastItem ? 1 : 0);
AnimatorSet animation = new AnimatorSet(); AnimatorSet animation = new AnimatorSet();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment