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 @@
android:toXScale="1"
android:fromYScale="0"
android:toYScale="1"
android:pivotX="95%" android:pivotY="5%"
android:pivotX="@fraction/menu_animation_pivot_x"
android:pivotY="5%"
android:duration="200" />
<alpha android:interpolator="@android:anim/linear_interpolator"
android:fromAlpha="0" android:toAlpha="1"
......
......@@ -10,7 +10,7 @@
android:toXScale="0.5"
android:fromYScale="1"
android:toYScale="0.5"
android:pivotX="95%"
android:pivotX="@fraction/menu_animation_pivot_x"
android:pivotY="5%"
android:duration="150" />
<alpha android:interpolator="@interpolator/fade_out_curve_interpolator"
......
......@@ -43,5 +43,4 @@
android:paddingStart="11dp"
android:background="?android:attr/listChoiceBackgroundIndicator"
android:scaleType="center" />
</LinearLayout>
\ No newline at end of file
......@@ -27,5 +27,5 @@
android:background="?android:attr/listChoiceBackgroundIndicator"
android:padding="10dp"
android:scaleType="fitCenter" />
</LinearLayout>
\ No newline at end of file
......@@ -3,10 +3,7 @@
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<resources>
<!-- Menu Dimensions -->
<!-- Necessary to align the menu with the bottom of the toolbar (the anchored button does not
extend to the bottom of the toolbar). -->
<dimen name="menu_vertical_offset">2dp</dimen>
</resources>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Menu Animation Constants -->
<item type="fraction" format="fraction" name="menu_animation_pivot_x">5%</item>
</resources>
\ No newline at end of file
......@@ -23,7 +23,6 @@
<item name="android:listPreferredItemPaddingStart">16dp</item>
<item name="android:listPreferredItemPaddingEnd">16dp</item>
<item name="android:textSize">16sp</item>
<item name="android:popupAnimationStyle">@style/OverflowMenuAnim</item>
</style>
<style name="OverflowMenuAnim">
<item name="android:windowEnterAnimation">@anim/menu_enter</item>
......
......@@ -17,7 +17,6 @@
<!-- Custom Menu dimensions -->
<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
via scrolling. -->
<dimen name="menu_vertical_fade_distance">15dp</dimen>
......
......@@ -11,4 +11,7 @@
<item type="id" name="button_secondary" />
<item type="id" name="button_tertiary" />
<item type="id" name="infobar_extra_check" />
<!-- Menu Animation Constants -->
<item type="fraction" format="fraction" name="menu_animation_pivot_x">95%</item>
</resources>
......@@ -37,7 +37,7 @@ import java.util.List;
*/
public class AppMenu implements OnItemClickListener, OnKeyListener {
/** 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;
......@@ -45,7 +45,6 @@ public class AppMenu implements OnItemClickListener, OnKeyListener {
private final int mItemRowHeight;
private final int mItemDividerHeight;
private final int mVerticalFadeDistance;
private final int mAdditionalVerticalOffset;
private ListPopupWindow mPopup;
private AppMenuAdapter mAdapter;
private AppMenuHandler mHandler;
......@@ -72,7 +71,6 @@ public class AppMenu implements OnItemClickListener, OnKeyListener {
mItemDividerHeight = itemDividerHeight;
assert mItemDividerHeight >= 0;
mAdditionalVerticalOffset = res.getDimensionPixelSize(R.dimen.menu_vertical_offset);
mVerticalFadeDistance = res.getDimensionPixelSize(R.dimen.menu_vertical_fade_distance);
}
......@@ -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
// 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();
mPopup.getBackground().getPadding(bgPadding);
......@@ -165,6 +169,7 @@ public class AppMenu implements OnItemClickListener, OnKeyListener {
popup.getBackground().getPadding(paddingRect);
int[] anchorLocation = new int[2];
popup.getAnchorView().getLocationInWindow(anchorLocation);
int anchorHeight = popup.getAnchorView().getHeight();
// If we have a hardware menu button, locate the app menu closer to the estimated
// hardware menu button location.
......@@ -187,11 +192,11 @@ public class AppMenu implements OnItemClickListener, OnKeyListener {
popup.setHorizontalOffset(horizontalOffset);
// The menu is displayed above the anchored view, so shift the menu up by the top
// padding of the background.
popup.setVerticalOffset(mAdditionalVerticalOffset - paddingRect.bottom);
popup.setVerticalOffset(-paddingRect.bottom);
} else {
// The menu is displayed below the anchored view, so shift the menu up by the top
// padding of the background.
popup.setVerticalOffset(mAdditionalVerticalOffset - paddingRect.top);
// The menu is displayed over and below the anchored view, so shift the menu up by the
// height of the anchor view.
popup.setVerticalOffset(-anchorHeight);
}
}
......@@ -264,9 +269,10 @@ public class AppMenu implements OnItemClickListener, OnKeyListener {
int[] anchorViewLocation = new int[2];
anchorView.getLocationOnScreen(anchorViewLocation);
anchorViewLocation[1] -= appDimensions.top;
int anchorViewImpactHeight = mIsByHardwareButton ? anchorView.getHeight() : 0;
int availableScreenSpace = Math.max(anchorViewLocation[1],
appDimensions.height() - anchorViewLocation[1] - anchorView.getHeight());
appDimensions.height() - anchorViewLocation[1] - anchorViewImpactHeight);
Rect padding = new Rect();
mPopup.getBackground().getPadding(padding);
......
......@@ -17,10 +17,13 @@ import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.ListView;
import android.widget.TextView;
import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.chrome.R;
import org.chromium.ui.base.LocalizationUtils;
import org.chromium.ui.interpolators.BakedBezierInterpolator;
import java.util.List;
......@@ -29,7 +32,7 @@ import java.util.List;
* ListAdapter to customize the view of items in the list.
*/
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.
......@@ -48,6 +51,11 @@ class AppMenuAdapter extends BaseAdapter {
* 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;
/**
* 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 */
private static final int ENTER_ITEM_DURATION_MS = 350;
......@@ -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_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 LayoutInflater mInflater;
private final List<MenuItem> mMenuItems;
......@@ -86,15 +98,16 @@ class AppMenuAdapter extends BaseAdapter {
@Override
public int getItemViewType(int position) {
MenuItem item = getItem(position);
boolean hasMenuButton = mShowMenuButton && position == 0;
int viewCount = item.hasSubMenu() ? item.getSubMenu().size() : 1;
if (mShowMenuButton && position == 0) viewCount++;
if (hasMenuButton) viewCount++;
if (viewCount == 4) {
return FOUR_BUTTON_MENU_ITEM;
} else if (viewCount == 3) {
return THREE_BUTTON_MENU_ITEM;
} else if (viewCount == 2) {
return TITLE_BUTTON_MENU_ITEM;
return hasMenuButton ? MENU_BUTTON_MENU_ITEM : TITLE_BUTTON_MENU_ITEM;
}
return STANDARD_MENU_ITEM;
}
......@@ -204,16 +217,21 @@ class AppMenuAdapter extends BaseAdapter {
convertView.setEnabled(false);
break;
}
case TITLE_BUTTON_MENU_ITEM: {
case TITLE_BUTTON_MENU_ITEM:
// Fall through.
case MENU_BUTTON_MENU_ITEM: {
TitleButtonMenuItemViewHolder holder = null;
if (convertView == null) {
holder = new TitleButtonMenuItemViewHolder();
convertView = mInflater.inflate(R.layout.title_button_menu_item, parent, false);
holder.title = (TextView) convertView.findViewById(R.id.title);
holder.button = (ImageButton) convertView.findViewById(R.id.button);
View animatedView = hasMenuButton ? holder.title : convertView;
convertView.setTag(holder);
convertView.setTag(R.id.menu_item_enter_anim_id,
buildStandardItemEnterAnimator(convertView, position));
buildStandardItemEnterAnimator(animatedView, position));
} else {
holder = (TitleButtonMenuItemViewHolder) convertView.getTag();
}
......@@ -275,6 +293,12 @@ class AppMenuAdapter extends BaseAdapter {
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 {
* @return The {@link Animator}.
*/
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);
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