11935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov/*
21935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov * Copyright (C) 2011 The Android Open Source Project
31935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov *
41935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov * Licensed under the Apache License, Version 2.0 (the "License");
51935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov * you may not use this file except in compliance with the License.
61935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov * You may obtain a copy of the License at
71935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov *
81935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov *      http://www.apache.org/licenses/LICENSE-2.0
91935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov *
101935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov * Unless required by applicable law or agreed to in writing, software
111935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov * distributed under the License is distributed on an "AS IS" BASIS,
121935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov * See the License for the specific language governing permissions and
141935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov * limitations under the License.
151935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov */
161935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov
171935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganovpackage android.support.v4.view;
181935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov
1930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.support.v4.internal.view.SupportMenuItem;
2030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.util.Log;
211935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganovimport android.view.MenuItem;
221935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganovimport android.view.View;
231935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov
241935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov/**
250574ca37da4619afe4e26753f5a1b4de314b6565Svetoslav Ganov * Helper for accessing features in {@link android.view.MenuItem}
260574ca37da4619afe4e26753f5a1b4de314b6565Svetoslav Ganov * introduced after API level 4 in a backwards compatible fashion.
271935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov */
281935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganovpublic class MenuItemCompat {
2930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    private static final String TAG = "MenuItemCompat";
301935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov
311935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    /**
321935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * Never show this item as a button in an Action Bar.
331935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     */
341935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    public static final int SHOW_AS_ACTION_NEVER = 0;
351935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov
361935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    /**
371935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * Show this item as a button in an Action Bar if the system
381935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * decides there is room for it.
391935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     */
401935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    public static final int SHOW_AS_ACTION_IF_ROOM = 1;
411935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov
421935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    /**
431935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * Always show this item as a button in an Action Bar. Use sparingly!
441935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * If too many items are set to always show in the Action Bar it can
451935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * crowd the Action Bar and degrade the user experience on devices with
461935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * smaller screens. A good rule of thumb is to have no more than 2
471935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * items set to always show at a time.
481935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     */
491935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    public static final int SHOW_AS_ACTION_ALWAYS = 2;
501935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov
511935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    /**
521935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * When this item is in the action bar, always show it with a
531935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * text label even if it also has an icon specified.
541935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     */
551935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    public static final int SHOW_AS_ACTION_WITH_TEXT = 4;
561935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov
571935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    /**
581935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * This item's action view collapses to a normal menu item.
591935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * When expanded, the action view temporarily takes over
601935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * a larger segment of its container.
611935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     */
621935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    public static final int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = 8;
631935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov
641935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    /**
651935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * Interface for the full API.
661935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     */
671935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    interface MenuVersionImpl {
6830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        boolean setShowAsAction(MenuItem item, int actionEnum);
6930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        MenuItem setActionView(MenuItem item, View view);
7030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        MenuItem setActionView(MenuItem item, int resId);
7130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        View getActionView(MenuItem item);
7230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        boolean expandActionView(MenuItem item);
7330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        boolean collapseActionView(MenuItem item);
7430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        boolean isActionViewExpanded(MenuItem item);
7530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        MenuItem setOnActionExpandListener(MenuItem item, OnActionExpandListener listener);
7630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    }
7730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
7830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    /**
7930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * Interface definition for a callback to be invoked when a menu item marked with {@link
8030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW} is expanded or collapsed.
8130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     *
8230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @see #expandActionView(android.view.MenuItem)
8330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @see #collapseActionView(android.view.MenuItem)
8430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @see #setShowAsAction(android.view.MenuItem, int)
8530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     */
8630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    public interface OnActionExpandListener {
8730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
8830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        /**
8930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell         * Called when a menu item with {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}
9030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell         * is expanded.
9130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell         *
9230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell         * @param item Item that was expanded
9330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell         * @return true if the item should expand, false if expansion should be suppressed.
9430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell         */
9530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        public boolean onMenuItemActionExpand(MenuItem item);
9630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
9730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        /**
9830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell         * Called when a menu item with {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}
9930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell         * is collapsed.
10030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell         *
10130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell         * @param item Item that was collapsed
10230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell         * @return true if the item should collapse, false if collapsing should be suppressed.
10330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell         */
10430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        public boolean onMenuItemActionCollapse(MenuItem item);
1051935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    }
1061935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov
1071935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    /**
1081935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * Interface implementation that doesn't use anything about v4 APIs.
1091935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     */
1101935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    static class BaseMenuVersionImpl implements MenuVersionImpl {
1111935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov        @Override
1121935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov        public boolean setShowAsAction(MenuItem item, int actionEnum) {
1131935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov            return false;
1141935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov        }
1151935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov
1161935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov        @Override
1171935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov        public MenuItem setActionView(MenuItem item, View view) {
1181935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov            return item;
1191935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov        }
12030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
12130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        @Override
12230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        public MenuItem setActionView(MenuItem item, int resId) {
12330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return item;
12430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
12530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
12630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        @Override
12730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        public View getActionView(MenuItem item) {
12830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return null;
12930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
13030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
13130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        @Override
13230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        public boolean expandActionView(MenuItem item) {
13330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return false;
13430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
13530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
13630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        @Override
13730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        public boolean collapseActionView(MenuItem item) {
13830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return false;
13930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
14030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
14130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        @Override
14230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        public boolean isActionViewExpanded(MenuItem item) {
14330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return false;
14430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
14530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
14630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        @Override
14730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        public MenuItem setOnActionExpandListener(MenuItem item, OnActionExpandListener listener) {
14830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return item;
14930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
1501935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    }
1511935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov
1521935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    /**
1531935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * Interface implementation for devices with at least v11 APIs.
1541935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     */
1551935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    static class HoneycombMenuVersionImpl implements MenuVersionImpl {
1561935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov        @Override
1571935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov        public boolean setShowAsAction(MenuItem item, int actionEnum) {
1581935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov            MenuItemCompatHoneycomb.setShowAsAction(item, actionEnum);
1591935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov            return true;
1601935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov        }
1611935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov        @Override
1621935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov        public MenuItem setActionView(MenuItem item, View view) {
1631935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov            return MenuItemCompatHoneycomb.setActionView(item, view);
1641935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov        }
16530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
16630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        @Override
16730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        public MenuItem setActionView(MenuItem item, int resId) {
16830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return MenuItemCompatHoneycomb.setActionView(item, resId);
16930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
17030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
17130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        @Override
17230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        public View getActionView(MenuItem item) {
17330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return MenuItemCompatHoneycomb.getActionView(item);
17430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
17530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
17630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        @Override
17730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        public boolean expandActionView(MenuItem item) {
17830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return false;
17930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
18030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
18130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        @Override
18230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        public boolean collapseActionView(MenuItem item) {
18330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return false;
18430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
18530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
18630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        @Override
18730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        public boolean isActionViewExpanded(MenuItem item) {
18830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return false;
18930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
19030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
19130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        @Override
19230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        public MenuItem setOnActionExpandListener(MenuItem item, OnActionExpandListener listener) {
19330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return item;
19430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
19530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    }
19630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
19730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    static class IcsMenuVersionImpl extends HoneycombMenuVersionImpl {
19830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        @Override
19930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        public boolean expandActionView(MenuItem item) {
20030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return MenuItemCompatIcs.expandActionView(item);
20130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
20230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
20330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        @Override
20430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        public boolean collapseActionView(MenuItem item) {
20530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return MenuItemCompatIcs.collapseActionView(item);
20630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
20730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
20830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        @Override
20930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        public boolean isActionViewExpanded(MenuItem item) {
21030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return MenuItemCompatIcs.isActionViewExpanded(item);
21130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
21230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
21330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        @Override
21430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        public MenuItem setOnActionExpandListener(MenuItem item,
21530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell                final OnActionExpandListener listener) {
21630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            if (listener == null) {
21730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell                return MenuItemCompatIcs.setOnActionExpandListener(item, null);
21830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            }
21930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            /*
22030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell             * MenuItemCompatIcs is a dependency of this segment of the support lib
22130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell             * but not the other way around, so we need to take an extra step here to proxy
22230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell             * to the right types.
22330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell             */
22430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return MenuItemCompatIcs.setOnActionExpandListener(item,
22530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell                    new MenuItemCompatIcs.SupportActionExpandProxy() {
22630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell                @Override
22730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell                public boolean onMenuItemActionExpand(MenuItem item) {
22830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell                    return listener.onMenuItemActionExpand(item);
22930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell                }
23030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
23130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell                @Override
23230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell                public boolean onMenuItemActionCollapse(MenuItem item) {
23330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell                    return listener.onMenuItemActionCollapse(item);
23430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell                }
23530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            });
23630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
2371935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    }
2381935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov
2391935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    /**
2401935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * Select the correct implementation to use for the current platform.
2411935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     */
2421935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    static final MenuVersionImpl IMPL;
2431935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    static {
24430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        final int version = android.os.Build.VERSION.SDK_INT;
24530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        if (version >= 14) {
24630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            IMPL = new IcsMenuVersionImpl();
24730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        } else if (version >= 11) {
2481935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov            IMPL = new HoneycombMenuVersionImpl();
2491935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov        } else {
2501935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov            IMPL = new BaseMenuVersionImpl();
2511935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov        }
2521935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    }
2531935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov
2541935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    // -------------------------------------------------------------------
2551935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov
2561935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    /**
2571935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * Call {@link MenuItem#setShowAsAction(int) MenuItem.setShowAsAction()}.
25830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * If running on a pre-{@link android.os.Build.VERSION_CODES#HONEYCOMB} device
25930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * and <code>item</code> does not implement {@link android.support.v4.internal.view.SupportMenuItem},
26030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * this method does nothing and returns false.  Otherwise returns true.
2611935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     */
2621935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    public static boolean setShowAsAction(MenuItem item, int actionEnum) {
26330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        if (item instanceof SupportMenuItem) {
26430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            ((SupportMenuItem) item).setShowAsAction(actionEnum);
26530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return true;
26630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
2671935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov        return IMPL.setShowAsAction(item, actionEnum);
2681935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    }
2691935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov
2701935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    /**
2711935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * Set an action view for this menu item. An action view will be displayed in place
2721935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * of an automatically generated menu item element in the UI when this item is shown
2731935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * as an action within a parent.
2741935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     *
27530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @param item the item to change
2761935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * @param view View to use for presenting this item to the user.
2771935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * @return This Item so additional setters can be called.
2781935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     *
2791935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     * @see #setShowAsAction(MenuItem, int)
2801935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov     */
2811935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    public static MenuItem setActionView(MenuItem item, View view) {
28230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        if (item instanceof SupportMenuItem) {
28330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return ((SupportMenuItem) item).setActionView(view);
28430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
2851935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov        return IMPL.setActionView(item, view);
2861935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov    }
28730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
28830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    /**
28930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * Set an action view for this menu item. An action view will be displayed in place
29030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * of an automatically generated menu item element in the UI when this item is shown
29130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * as an action within a parent.
29230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * <p>
29330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     *   <strong>Note:</strong> Setting an action view overrides the action provider
29430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     *           set via {@link #setActionProvider(MenuItem, ActionProvider)}.
29530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * </p>
29630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     *
29730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @param item the item to change
29830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @param resId Layout resource to use for presenting this item to the user.
29930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @return This Item so additional setters can be called.
30030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     *
30130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @see #setShowAsAction(MenuItem, int)
30230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     */
30330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    public static MenuItem setActionView(MenuItem item, int resId) {
30430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        if (item instanceof SupportMenuItem) {
30530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return ((SupportMenuItem) item).setActionView(resId);
30630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
30730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        return IMPL.setActionView(item, resId);
30830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    }
30930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
31030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    /**
31130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * Returns the currently set action view for this menu item.
31230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     *
31330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @param item the item to query
31430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @return This item's action view
31530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     */
31630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    public static View getActionView(MenuItem item) {
31730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        if (item instanceof SupportMenuItem) {
31830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return ((SupportMenuItem) item).getActionView();
31930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
32030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        return IMPL.getActionView(item);
32130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    }
32230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
32330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    /**
32430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * Sets the {@link ActionProvider} responsible for creating an action view if
32530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * the item is placed on the action bar. The provider also provides a default
32630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * action invoked if the item is placed in the overflow menu.
32730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * <p>
32830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     *   <strong>Note:</strong> Setting an action provider overrides the action view
32930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     *           set via {@link #setActionView(MenuItem, View)}.
33030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * </p>
33130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     *
33230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @param item item to change
33330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @param provider The action provider.
33430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @return This Item so additional setters can be called.
33530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     *
33630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @see ActionProvider
33730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     */
33830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    public static MenuItem setActionProvider(MenuItem item, ActionProvider provider) {
33930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        if (item instanceof SupportMenuItem) {
34030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return ((SupportMenuItem) item).setSupportActionProvider(provider);
34130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
34230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        // TODO Wrap the support ActionProvider and assign it
34330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        Log.w(TAG, "setActionProvider: item does not implement SupportMenuItem; ignoring");
34430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        return item;
34530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    }
34630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
34730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    /**
34830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * Gets the {@link ActionProvider}.
34930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     *
35030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @return The action provider.
35130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     *
35230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @see ActionProvider
35330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @see #setActionProvider(MenuItem, ActionProvider)
35430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     */
35530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    public static ActionProvider getActionProvider(MenuItem item) {
35630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        if (item instanceof SupportMenuItem) {
35730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return ((SupportMenuItem) item).getSupportActionProvider();
35830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
35930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
36030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        // TODO Wrap the framework ActionProvider and return it
36130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        Log.w(TAG, "getActionProvider: item does not implement SupportMenuItem; returning null");
36230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        return null;
36330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    }
36430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
36530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    /**
36630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * Expand the action view associated with this menu item.
36730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * The menu item must have an action view set, as well as
36830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * the showAsAction flag {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}.
36930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * If a listener has been set using
37030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * {@link #setOnActionExpandListener(MenuItem, OnActionExpandListener)}
37130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * it will have its {@link OnActionExpandListener#onMenuItemActionExpand(MenuItem)}
37230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * method invoked. The listener may return false from this method to prevent expanding
37330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * the action view.
37430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     *
37530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @return true if the action view was expanded, false otherwise.
37630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     */
37730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    public static boolean expandActionView(MenuItem item) {
37830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        if (item instanceof SupportMenuItem) {
37930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return ((SupportMenuItem) item).expandActionView();
38030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
38130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        return IMPL.expandActionView(item);
38230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    }
38330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
38430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    /**
38530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * Collapse the action view associated with this menu item. The menu item must have an action
38630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * view set, as well as the showAsAction flag {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}. If a
38730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * listener has been set using {@link #setOnActionExpandListener(MenuItem,
38830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * android.support.v4.view.MenuItemCompat.OnActionExpandListener)}
38930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * it will have its {@link
39030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * android.support.v4.view.MenuItemCompat.OnActionExpandListener#onMenuItemActionCollapse(MenuItem)}
39130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * method invoked. The listener may return false from this method to prevent collapsing
39230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * the action view.
39330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     *
39430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @return true if the action view was collapsed, false otherwise.
39530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     */
39630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    public static boolean collapseActionView(MenuItem item) {
39730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        if (item instanceof SupportMenuItem) {
39830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return ((SupportMenuItem) item).collapseActionView();
39930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
40030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        return IMPL.collapseActionView(item);
40130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    }
40230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
40330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    /**
40430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * Returns true if this menu item's action view has been expanded.
40530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     *
40630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @return true if the item's action view is expanded, false otherwise.
40730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @see #expandActionView(MenuItem)
40830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @see #collapseActionView(MenuItem)
40930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @see #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW
41030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @see android.support.v4.view.MenuItemCompat.OnActionExpandListener
41130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     */
41230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    public static boolean isActionViewExpanded(MenuItem item) {
41330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        if (item instanceof SupportMenuItem) {
41430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return ((SupportMenuItem) item).isActionViewExpanded();
41530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
41630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        return IMPL.isActionViewExpanded(item);
41730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    }
41830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell
41930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    /**
42030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * Set an {@link android.support.v4.view.MenuItemCompat.OnActionExpandListener} on this menu
42130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * item to be notified when the associated action view is expanded or collapsed.
42230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * The menu item must be configured to expand or collapse its action view using the flag
42330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}.
42430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     *
42530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @param listener Listener that will respond to expand/collapse events
42630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     * @return This menu item instance for call chaining
42730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell     */
42830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    public static MenuItem setOnActionExpandListener(MenuItem item,
42930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            OnActionExpandListener listener) {
43030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        if (item instanceof SupportMenuItem) {
43130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell            return ((SupportMenuItem) item).setSupportOnActionExpandListener(listener);
43230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        }
43330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        return IMPL.setOnActionExpandListener(item, listener);
43430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    }
4351935ed3af7c6545bc38adfdc6026d87a3249222fSvetoslav Ganov}
436