X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fchrome%2Fandroid%2Fjava%2Fsrc%2Forg%2Fchromium%2Fchrome%2Fbrowser%2Fappmenu%2FAppMenuAdapter.java;h=2b60292ce451fd34132a30b701cd5b671b51d743;hb=490a4587e7e356282cb1453efaf36de4acc9762f;hp=6bf7f43074c9761b8b3a162887264bb3441a548e;hpb=3a51af92707b9c600d06a404c9db8f07fcd50959;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java b/src/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java index 6bf7f43..2b60292 100644 --- a/src/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java +++ b/src/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java @@ -4,6 +4,10 @@ package org.chromium.chrome.browser.appmenu; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; import android.graphics.drawable.Drawable; import android.view.LayoutInflater; import android.view.MenuItem; @@ -12,10 +16,15 @@ import android.view.View.OnClickListener; 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; @@ -23,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. @@ -42,17 +51,38 @@ 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; + private static final int ENTER_ITEM_BASE_DELAY_MS = 80; + private static final int ENTER_ITEM_ADDL_DELAY_MS = 30; + 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 = 21.f; private final AppMenu mAppMenu; private final LayoutInflater mInflater; private final List mMenuItems; private final int mNumMenuItems; + private final boolean mShowMenuButton; + private final float mDpToPx; - public AppMenuAdapter(AppMenu appMenu, List menuItems, LayoutInflater inflater) { + public AppMenuAdapter(AppMenu appMenu, List menuItems, LayoutInflater inflater, + boolean showMenuButton) { mAppMenu = appMenu; mMenuItems = menuItems; mInflater = inflater; mNumMenuItems = menuItems.size(); + mShowMenuButton = showMenuButton; + mDpToPx = inflater.getContext().getResources().getDisplayMetrics().density; } @Override @@ -67,14 +97,17 @@ class AppMenuAdapter extends BaseAdapter { @Override public int getItemViewType(int position) { - if (getItem(position).hasSubMenu()) { - if (getItem(position).getSubMenu().size() == 4) { - return FOUR_BUTTON_MENU_ITEM; - } else if (getItem(position).getSubMenu().size() == 3) { - return THREE_BUTTON_MENU_ITEM; - } else if (getItem(position).getSubMenu().size() == 2) { - return TITLE_BUTTON_MENU_ITEM; - } + MenuItem item = getItem(position); + boolean hasMenuButton = mShowMenuButton && position == 0; + int viewCount = item.hasSubMenu() ? item.getSubMenu().size() : 1; + 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 hasMenuButton ? MENU_BUTTON_MENU_ITEM : TITLE_BUTTON_MENU_ITEM; } return STANDARD_MENU_ITEM; } @@ -94,6 +127,7 @@ class AppMenuAdapter extends BaseAdapter { @Override public View getView(int position, View convertView, ViewGroup parent) { + final boolean hasMenuButton = mShowMenuButton && position == 0; final MenuItem item = getItem(position); switch (getItemViewType(position)) { case STANDARD_MENU_ITEM: { @@ -104,6 +138,8 @@ class AppMenuAdapter extends BaseAdapter { holder.text = (TextView) convertView.findViewById(R.id.menu_item_text); holder.image = (AppMenuItemIcon) convertView.findViewById(R.id.menu_item_icon); convertView.setTag(holder); + convertView.setTag(R.id.menu_item_enter_anim_id, + buildStandardItemEnterAnimator(convertView, position)); } else { holder = (StandardMenuItemViewHolder) convertView.getTag(); } @@ -133,16 +169,23 @@ class AppMenuAdapter extends BaseAdapter { if (convertView == null) { holder = new ThreeButtonMenuItemViewHolder(); convertView = mInflater.inflate(R.layout.three_button_menu_item, parent, false); - holder.buttonOne = (ImageButton) convertView.findViewById(R.id.button_one); - holder.buttonTwo = (ImageButton) convertView.findViewById(R.id.button_two); - holder.buttonThree = (ImageButton) convertView.findViewById(R.id.button_three); + holder.buttons[0] = (ImageButton) convertView.findViewById(R.id.button_one); + holder.buttons[1] = (ImageButton) convertView.findViewById(R.id.button_two); + holder.buttons[2] = (ImageButton) convertView.findViewById(R.id.button_three); convertView.setTag(holder); + convertView.setTag(R.id.menu_item_enter_anim_id, + buildIconItemEnterAnimator(holder.buttons, hasMenuButton)); } else { holder = (ThreeButtonMenuItemViewHolder) convertView.getTag(); } - setupImageButton(holder.buttonOne, item.getSubMenu().getItem(0)); - setupImageButton(holder.buttonTwo, item.getSubMenu().getItem(1)); - setupImageButton(holder.buttonThree, item.getSubMenu().getItem(2)); + setupImageButton(holder.buttons[0], item.getSubMenu().getItem(0)); + setupImageButton(holder.buttons[1], item.getSubMenu().getItem(1)); + if (hasMenuButton) { + setupMenuButton(holder.buttons[3]); + } else { + setupImageButton(holder.buttons[2], item.getSubMenu().getItem(2)); + } + convertView.setFocusable(false); convertView.setEnabled(false); break; @@ -152,34 +195,47 @@ class AppMenuAdapter extends BaseAdapter { if (convertView == null) { holder = new FourButtonMenuItemViewHolder(); convertView = mInflater.inflate(R.layout.four_button_menu_item, parent, false); - holder.buttonOne = (ImageButton) convertView.findViewById(R.id.button_one); - holder.buttonTwo = (ImageButton) convertView.findViewById(R.id.button_two); - holder.buttonThree = (ImageButton) convertView.findViewById(R.id.button_three); - holder.buttonFour = (ImageButton) convertView.findViewById(R.id.button_four); + holder.buttons[0] = (ImageButton) convertView.findViewById(R.id.button_one); + holder.buttons[1] = (ImageButton) convertView.findViewById(R.id.button_two); + holder.buttons[2] = (ImageButton) convertView.findViewById(R.id.button_three); + holder.buttons[3] = (ImageButton) convertView.findViewById(R.id.button_four); convertView.setTag(holder); + convertView.setTag(R.id.menu_item_enter_anim_id, + buildIconItemEnterAnimator(holder.buttons, hasMenuButton)); } else { holder = (FourButtonMenuItemViewHolder) convertView.getTag(); } - setupImageButton(holder.buttonOne, item.getSubMenu().getItem(0)); - setupImageButton(holder.buttonTwo, item.getSubMenu().getItem(1)); - setupImageButton(holder.buttonThree, item.getSubMenu().getItem(2)); - setupImageButton(holder.buttonFour, item.getSubMenu().getItem(3)); + setupImageButton(holder.buttons[0], item.getSubMenu().getItem(0)); + setupImageButton(holder.buttons[1], item.getSubMenu().getItem(1)); + setupImageButton(holder.buttons[2], item.getSubMenu().getItem(2)); + if (hasMenuButton) { + setupMenuButton(holder.buttons[3]); + } else { + setupImageButton(holder.buttons[3], item.getSubMenu().getItem(3)); + } convertView.setFocusable(false); 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(animatedView, position)); } else { holder = (TitleButtonMenuItemViewHolder) convertView.getTag(); } - final MenuItem titleItem = item.getSubMenu().getItem(0); + final MenuItem titleItem = item.hasSubMenu() ? item.getSubMenu().getItem(0) : item; holder.title.setText(titleItem.getTitle()); holder.title.setEnabled(titleItem.isEnabled()); holder.title.setFocusable(titleItem.isEnabled()); @@ -189,7 +245,11 @@ class AppMenuAdapter extends BaseAdapter { mAppMenu.onItemClick(titleItem); } }); - if (item.getSubMenu().getItem(1).getIcon() != null) { + + if (hasMenuButton) { + holder.button.setVisibility(View.VISIBLE); + setupMenuButton(holder.button); + } else if (item.getSubMenu().getItem(1).getIcon() != null) { holder.button.setVisibility(View.VISIBLE); setupImageButton(holder.button, item.getSubMenu().getItem(1)); } else { @@ -206,7 +266,11 @@ class AppMenuAdapter extends BaseAdapter { } private void setupImageButton(ImageButton button, final MenuItem item) { + // Store and recover the level of image as button.setimageDrawable + // resets drawable to default level. + int currentLevel = item.getIcon().getLevel(); button.setImageDrawable(item.getIcon()); + item.getIcon().setLevel(currentLevel); button.setContentDescription(item.getTitle()); button.setEnabled(item.isEnabled()); button.setFocusable(item.isEnabled()); @@ -218,22 +282,111 @@ class AppMenuAdapter extends BaseAdapter { }); } + private void setupMenuButton(ImageButton button) { + button.setImageResource(R.drawable.btn_menu_pressed); + button.setContentDescription(button.getResources().getString(R.string.menu_dismiss_btn)); + button.setEnabled(true); + button.setFocusable(true); + button.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + 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); + } + + /** + * This builds an {@link Animator} for the enter animation of a standard menu item. This means + * it will animate the alpha from 0 to 1 and translate the view from -10dp to 0dp on the y axis. + * + * @param view The menu item {@link View} to be animated. + * @param position The position in the menu. This impacts the start delay of the animation. + * @return The {@link Animator}. + */ + private Animator buildStandardItemEnterAnimator(final View view, int position) { + final float offsetYPx = ENTER_STANDARD_ITEM_OFFSET_Y_DP * mDpToPx; + final int startDelay = ENTER_ITEM_BASE_DELAY_MS + ENTER_ITEM_ADDL_DELAY_MS * position; + + AnimatorSet animation = new AnimatorSet(); + animation.playTogether( + ObjectAnimator.ofFloat(view, View.ALPHA, 0.f, 1.f), + ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, offsetYPx, 0.f)); + animation.setDuration(ENTER_ITEM_DURATION_MS); + animation.setStartDelay(startDelay); + animation.setInterpolator(BakedBezierInterpolator.FADE_IN_CURVE); + + animation.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + view.setAlpha(0.f); + } + }); + return animation; + } + + /** + * This builds an {@link Animator} for the enter animation of icon row menu items. This means + * it will animate the alpha from 0 to 1 and translate the views from 10dp to 0dp on the x axis. + * + * @param views The list if icons in the menu item that should be animated. + * @param skipLastItem Whether or not the last item should be animated or not. + * @return The {@link Animator}. + */ + private Animator buildIconItemEnterAnimator(final ImageView[] views, boolean skipLastItem) { + 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(); + AnimatorSet.Builder builder = null; + for (int i = 0; i < maxViewsToAnimate; i++) { + final int startDelay = ENTER_ITEM_ADDL_DELAY_MS * i; + + Animator alpha = ObjectAnimator.ofFloat(views[i], View.ALPHA, 0.f, 1.f); + Animator translate = ObjectAnimator.ofFloat(views[i], View.TRANSLATION_X, offsetXPx, 0); + alpha.setStartDelay(startDelay); + translate.setStartDelay(startDelay); + alpha.setDuration(ENTER_ITEM_DURATION_MS); + translate.setDuration(ENTER_ITEM_DURATION_MS); + + if (builder == null) { + builder = animation.play(alpha); + } else { + builder.with(alpha); + } + builder.with(translate); + } + animation.setStartDelay(ENTER_ITEM_BASE_DELAY_MS); + animation.setInterpolator(BakedBezierInterpolator.FADE_IN_CURVE); + + animation.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + for (int i = 0; i < maxViewsToAnimate; i++) { + views[i].setAlpha(0.f); + } + } + }); + return animation; + } + static class StandardMenuItemViewHolder { public TextView text; public AppMenuItemIcon image; } static class ThreeButtonMenuItemViewHolder { - public ImageButton buttonOne; - public ImageButton buttonTwo; - public ImageButton buttonThree; + public ImageButton[] buttons = new ImageButton[3]; } static class FourButtonMenuItemViewHolder { - public ImageButton buttonOne; - public ImageButton buttonTwo; - public ImageButton buttonThree; - public ImageButton buttonFour; + public ImageButton[] buttons = new ImageButton[4]; } static class TitleButtonMenuItemViewHolder {