Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0a1a5e37 authored by Alan Viverette's avatar Alan Viverette Committed by Android (Google) Code Review
Browse files

Merge "Reduce CascadingMenuPopup's reliance on internal ListView state"

parents 78a8df49 00aa5103
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -788,7 +788,7 @@ public class ActionMenuPresenter extends BaseMenuPresenter
            // Not a submenu, but treat it like one.
            super.onSubMenuSelected(null);
        } else {
            mMenu.close(false);
            mMenu.close(false /* closeAllMenus */);
        }
    }

@@ -981,7 +981,7 @@ public class ActionMenuPresenter extends BaseMenuPresenter
        @Override
        public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
            if (menu instanceof SubMenuBuilder) {
                ((SubMenuBuilder) menu).getRootMenu().close(false);
                menu.getRootMenu().close(false /* closeAllMenus */);
            }
            final Callback cb = getCallback();
            if (cb != null) {
+7 −20
Original line number Diff line number Diff line
@@ -127,13 +127,15 @@ public class DropDownListView extends ListView {
    }

    @Override
    protected boolean shouldShowSelector() {
        View selectedView = getSelectedView();
        return selectedView != null && selectedView.isEnabled() || super.shouldShowSelector();
    boolean shouldShowSelector() {
        return isHovered() || super.shouldShowSelector();
    }

    @Override
    public boolean onHoverEvent(MotionEvent ev) {
        // Allow the super class to handle hover state management first.
        final boolean handled = super.onHoverEvent(ev);

        final int action = ev.getActionMasked();
        if (action == MotionEvent.ACTION_HOVER_ENTER
                || action == MotionEvent.ACTION_HOVER_MOVE) {
@@ -154,26 +156,11 @@ public class DropDownListView extends ListView {
            // Do not cancel the selected position if the selection is visible by other reasons.
            if (!super.shouldShowSelector()) {
                setSelectedPositionInt(INVALID_POSITION);
                setNextSelectedPositionInt(INVALID_POSITION);
            }
        }
        return super.onHoverEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        final int x = (int) event.getX();
        final int y = (int) event.getY();
        final int position = pointToPosition(x, y);
        if (position == INVALID_POSITION) {
            return super.onTouchEvent(event);
        }

        if (position != mSelectedPosition) {
            setSelectedPositionInt(position);
            setNextSelectedPositionInt(position);
        }

        return super.onTouchEvent(event);
        return handled;
    }

    /**
+21 −1
Original line number Diff line number Diff line
@@ -2,6 +2,9 @@ package android.widget;

import com.android.internal.view.menu.MenuBuilder;

import android.annotation.NonNull;
import android.view.MenuItem;

/**
 * An interface notified when a menu item is hovered. Useful for cases when hover should trigger
 * some behavior at a higher level, like managing the opening and closing of submenus.
@@ -9,5 +12,22 @@ import com.android.internal.view.menu.MenuBuilder;
 * @hide
 */
public interface MenuItemHoverListener {
    public void onItemHovered(MenuBuilder menu, int position);
    /**
     * Called when hover exits a menu item.
     * <p>
     * If hover is moving to another item, this method will be called before
     * {@link #onItemHoverEnter(MenuBuilder, MenuItem)} for the newly-hovered item.
     *
     * @param menu the item's parent menu
     * @param item the hovered menu item
     */
    void onItemHoverExit(@NonNull MenuBuilder menu, @NonNull MenuItem item);

    /**
     * Called when hover enters a menu item.
     *
     * @param menu the item's parent menu
     * @param item the hovered menu item
     */
    void onItemHoverEnter(@NonNull MenuBuilder menu, @NonNull MenuItem item);
}
+52 −28
Original line number Diff line number Diff line
@@ -16,12 +16,14 @@

package android.widget;

import android.annotation.NonNull;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.transition.Transition;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;

@@ -72,10 +74,18 @@ public class MenuPopupWindow extends ListPopupWindow implements MenuItemHoverLis
    }

    @Override
    public void onItemHovered(MenuBuilder menu, int position) {
    public void onItemHoverEnter(@NonNull MenuBuilder menu, @NonNull MenuItem item) {
        // Forward up the chain
        if (mHoverListener != null) {
            mHoverListener.onItemHovered(menu, position);
            mHoverListener.onItemHoverEnter(menu, item);
        }
    }

    @Override
    public void onItemHoverExit(@NonNull MenuBuilder menu, @NonNull MenuItem item) {
        // Forward up the chain
        if (mHoverListener != null) {
            mHoverListener.onItemHoverExit(menu, item);
        }
    }

@@ -87,6 +97,7 @@ public class MenuPopupWindow extends ListPopupWindow implements MenuItemHoverLis
        final int mRetreatKey;

        private MenuItemHoverListener mHoverListener;
        private MenuItem mHoveredMenuItem;

        public MenuDropDownListView(Context context, boolean hijackFocus) {
            super(context, hijackFocus);
@@ -115,8 +126,7 @@ public class MenuPopupWindow extends ListPopupWindow implements MenuItemHoverLis
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            ListMenuItemView selectedItem = (ListMenuItemView) getSelectedView();
            if (selectedItem != null && keyCode == mAdvanceKey) {
                if (selectedItem.isEnabled() &&
                        ((ListMenuItemView) selectedItem).getItemData().hasSubMenu()) {
                if (selectedItem.isEnabled() && selectedItem.getItemData().hasSubMenu()) {
                    performItemClick(
                            selectedItem,
                            getSelectedItemPosition(),
@@ -127,7 +137,8 @@ public class MenuPopupWindow extends ListPopupWindow implements MenuItemHoverLis
                setSelectedPositionInt(INVALID_POSITION);
                setNextSelectedPositionInt(INVALID_POSITION);

                ((MenuAdapter) getAdapter()).getAdapterMenu().close();
                // Close only the top-level menu.
                ((MenuAdapter) getAdapter()).getAdapterMenu().close(false /* closeAllMenus */);
                return true;
            }
            return super.onKeyDown(keyCode, event);
@@ -135,36 +146,49 @@ public class MenuPopupWindow extends ListPopupWindow implements MenuItemHoverLis

        @Override
        public boolean onHoverEvent(MotionEvent ev) {
            boolean dispatchHover = false;
            final int position = pointToPosition((int) ev.getX(), (int) ev.getY());
            // Dispatch any changes in hovered item index to the listener.
            if (mHoverListener != null) {
                // The adapter may be wrapped. Adjust the index if necessary.
                final int headersCount;
                final MenuAdapter menuAdapter;
                final ListAdapter adapter = getAdapter();
                if (adapter instanceof HeaderViewListAdapter) {
                    final HeaderViewListAdapter headerAdapter = (HeaderViewListAdapter) adapter;
                    headersCount = headerAdapter.getHeadersCount();
                    menuAdapter = (MenuAdapter) headerAdapter.getWrappedAdapter();
                } else {
                    headersCount = 0;
                    menuAdapter = (MenuAdapter) adapter;
                }

            final int action = ev.getActionMasked();
            if (action == MotionEvent.ACTION_HOVER_ENTER
                    || action == MotionEvent.ACTION_HOVER_MOVE) {
                if (position != INVALID_POSITION && position != mSelectedPosition) {
                    final View hoveredItem = getChildAt(position - getFirstVisiblePosition());
                    if (hoveredItem.isEnabled()) {
                        dispatchHover = true;
                // Find the menu item for the view at the event coordinates.
                MenuItem menuItem = null;
                if (ev.getAction() != MotionEvent.ACTION_HOVER_EXIT) {
                    final int position = pointToPosition((int) ev.getX(), (int) ev.getY());
                    if (position != INVALID_POSITION) {
                        final int itemPosition = position - headersCount;
                        if (itemPosition >= 0 && itemPosition < menuAdapter.getCount()) {
                            menuItem = menuAdapter.getItem(itemPosition);
                        }
                    }
                }

            boolean superVal = super.onHoverEvent(ev);

            if (dispatchHover && mHoverListener != null) {
                ListAdapter adapter = getAdapter();
                MenuAdapter menuAdapter;
                if (adapter instanceof HeaderViewListAdapter) {
                    menuAdapter = (MenuAdapter) ((HeaderViewListAdapter) adapter)
                            .getWrappedAdapter();
                } else {
                    menuAdapter = (MenuAdapter) adapter;
                final MenuItem oldMenuItem = mHoveredMenuItem;
                if (oldMenuItem != menuItem) {
                    final MenuBuilder menu = menuAdapter.getAdapterMenu();
                    if (oldMenuItem != null) {
                        mHoverListener.onItemHoverExit(menu, oldMenuItem);
                    }

                mHoverListener.onItemHovered(menuAdapter.getAdapterMenu(), position);
                    mHoveredMenuItem = menuItem;

                    if (menuItem != null) {
                        mHoverListener.onItemHoverEnter(menu, menuItem);
                    }
                }
            }

            return superVal;
            return super.onHoverEvent(ev);
        }
    }
}
 No newline at end of file
+316 −198

File changed.

Preview size limit exceeded, changes collapsed.

Loading