1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.support.v4.view;
18
19import android.content.res.ColorStateList;
20import android.graphics.PorterDuff;
21import android.graphics.drawable.Drawable;
22import android.support.annotation.RequiresApi;
23import android.support.v4.internal.view.SupportMenuItem;
24import android.support.v4.os.BuildCompat;
25import android.util.Log;
26import android.view.KeyEvent;
27import android.view.Menu;
28import android.view.MenuItem;
29import android.view.View;
30
31/**
32 * Helper for accessing features in {@link android.view.MenuItem}
33 * introduced after API level 14 in a backwards compatible fashion.
34 * <p class="note"><strong>Note:</strong> You cannot get an instance of this class. Instead,
35 * it provides <em>static</em> methods that correspond to the methods in {@link
36 * android.view.MenuItem}, but take a {@link android.view.MenuItem} object as an additional
37 * argument.</p>
38 */
39public final class MenuItemCompat {
40    private static final String TAG = "MenuItemCompat";
41
42    /**
43     * Never show this item as a button in an Action Bar.
44     *
45     * @deprecated Use {@link MenuItem#SHOW_AS_ACTION_NEVER} directly.
46     */
47    @Deprecated
48    public static final int SHOW_AS_ACTION_NEVER = 0;
49
50    /**
51     * Show this item as a button in an Action Bar if the system
52     * decides there is room for it.
53     *
54     * @deprecated Use {@link MenuItem#SHOW_AS_ACTION_IF_ROOM} directly.
55     */
56    @Deprecated
57    public static final int SHOW_AS_ACTION_IF_ROOM = 1;
58
59    /**
60     * Always show this item as a button in an Action Bar. Use sparingly!
61     * If too many items are set to always show in the Action Bar it can
62     * crowd the Action Bar and degrade the user experience on devices with
63     * smaller screens. A good rule of thumb is to have no more than 2
64     * items set to always show at a time.
65     *
66     * @deprecated Use {@link MenuItem#SHOW_AS_ACTION_ALWAYS} directly.
67     */
68    @Deprecated
69    public static final int SHOW_AS_ACTION_ALWAYS = 2;
70
71    /**
72     * When this item is in the action bar, always show it with a
73     * text label even if it also has an icon specified.
74     *
75     * @deprecated Use {@link MenuItem#SHOW_AS_ACTION_WITH_TEXT} directly.
76     */
77    @Deprecated
78    public static final int SHOW_AS_ACTION_WITH_TEXT = 4;
79
80    /**
81     * This item's action view collapses to a normal menu item.
82     * When expanded, the action view temporarily takes over
83     * a larger segment of its container.
84     *
85     * @deprecated Use {@link MenuItem#SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW} directly.
86     */
87    @Deprecated
88    public static final int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = 8;
89
90    /**
91     * Interface for the full API.
92     */
93    interface MenuVersionImpl {
94        void setContentDescription(MenuItem item, CharSequence contentDescription);
95        CharSequence getContentDescription(MenuItem item);
96        void setTooltipText(MenuItem item, CharSequence tooltipText);
97        CharSequence getTooltipText(MenuItem item);
98        void setShortcut(MenuItem item, char numericChar, char alphaChar, int numericModifiers,
99                int alphaModifiers);
100        void setAlphabeticShortcut(MenuItem item, char alphaChar, int alphaModifiers);
101        int getAlphabeticModifiers(MenuItem item);
102        void setNumericShortcut(MenuItem item, char numericChar, int numericModifiers);
103        int getNumericModifiers(MenuItem item);
104        void setIconTintList(MenuItem item, ColorStateList tint);
105        ColorStateList getIconTintList(MenuItem item);
106        void setIconTintMode(MenuItem item, PorterDuff.Mode tintMode);
107        PorterDuff.Mode getIconTintMode(MenuItem item);
108    }
109
110    /**
111     * Interface definition for a callback to be invoked when a menu item marked with {@link
112     * #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW} is expanded or collapsed.
113     *
114     * @see #expandActionView(android.view.MenuItem)
115     * @see #collapseActionView(android.view.MenuItem)
116     * @see #setShowAsAction(android.view.MenuItem, int)
117     *
118     * @deprecated Use {@link MenuItem.OnActionExpandListener} directly.
119     */
120    @Deprecated
121    public interface OnActionExpandListener {
122
123        /**
124         * Called when a menu item with {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}
125         * is expanded.
126         *
127         * @param item Item that was expanded
128         * @return true if the item should expand, false if expansion should be suppressed.
129         */
130        boolean onMenuItemActionExpand(MenuItem item);
131
132        /**
133         * Called when a menu item with {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}
134         * is collapsed.
135         *
136         * @param item Item that was collapsed
137         * @return true if the item should collapse, false if collapsing should be suppressed.
138         */
139        boolean onMenuItemActionCollapse(MenuItem item);
140    }
141
142    static class MenuItemCompatBaseImpl implements MenuVersionImpl {
143        @Override
144        public void setContentDescription(MenuItem item, CharSequence contentDescription) {
145        }
146
147        @Override
148        public CharSequence getContentDescription(MenuItem item) {
149            return null;
150        }
151
152        @Override
153        public void setTooltipText(MenuItem item, CharSequence tooltipText) {
154        }
155
156        @Override
157        public CharSequence getTooltipText(MenuItem item) {
158            return null;
159        }
160
161        @Override
162        public void setShortcut(MenuItem item, char numericChar, char alphaChar,
163                int numericModifiers, int alphaModifiers) {
164        }
165
166        @Override
167        public void setAlphabeticShortcut(MenuItem item, char alphaChar, int alphaModifiers) {
168        }
169
170        @Override
171        public int getAlphabeticModifiers(MenuItem item) {
172            return 0;
173        }
174
175        @Override
176        public void setNumericShortcut(MenuItem item, char numericChar, int numericModifiers) {
177        }
178
179        @Override
180        public int getNumericModifiers(MenuItem item) {
181            return 0;
182        }
183
184        @Override
185        public void setIconTintList(MenuItem item, ColorStateList tint) {
186        }
187
188        @Override
189        public ColorStateList getIconTintList(MenuItem item) {
190            return null;
191        }
192
193        @Override
194        public void setIconTintMode(MenuItem item, PorterDuff.Mode tintMode) {
195        }
196
197        @Override
198        public PorterDuff.Mode getIconTintMode(MenuItem item) {
199            return null;
200        }
201    }
202
203    @RequiresApi(26)
204    static class MenuItemCompatApi26Impl extends MenuItemCompatBaseImpl {
205        @Override
206        public void setContentDescription(MenuItem item, CharSequence contentDescription) {
207            item.setContentDescription(contentDescription);
208        }
209
210        @Override
211        public CharSequence getContentDescription(MenuItem item) {
212            return item.getContentDescription();
213        }
214
215        @Override
216        public void setTooltipText(MenuItem item, CharSequence tooltipText) {
217            item.setTooltipText(tooltipText);
218        }
219
220        @Override
221        public CharSequence getTooltipText(MenuItem item) {
222            return item.getTooltipText();
223        }
224
225        @Override
226        public void setShortcut(MenuItem item, char numericChar, char alphaChar,
227                int numericModifiers, int alphaModifiers) {
228            item.setShortcut(numericChar, alphaChar, numericModifiers, alphaModifiers);
229        }
230
231        @Override
232        public void setAlphabeticShortcut(MenuItem item, char alphaChar, int alphaModifiers) {
233            item.setAlphabeticShortcut(alphaChar, alphaModifiers);
234        }
235
236        @Override
237        public int getAlphabeticModifiers(MenuItem item) {
238            return item.getAlphabeticModifiers();
239        }
240
241        @Override
242        public void setNumericShortcut(MenuItem item, char numericChar, int numericModifiers) {
243            item.setNumericShortcut(numericChar, numericModifiers);
244        }
245
246        @Override
247        public int getNumericModifiers(MenuItem item) {
248            return item.getNumericModifiers();
249        }
250
251        @Override
252        public void setIconTintList(MenuItem item, ColorStateList tint) {
253            item.setIconTintList(tint);
254        }
255
256        @Override
257        public ColorStateList getIconTintList(MenuItem item) {
258            return item.getIconTintList();
259        }
260
261        @Override
262        public void setIconTintMode(MenuItem item, PorterDuff.Mode tintMode) {
263            item.setIconTintMode(tintMode);
264        }
265
266        @Override
267        public PorterDuff.Mode getIconTintMode(MenuItem item) {
268            return item.getIconTintMode();
269        }
270    }
271
272    /**
273     * Select the correct implementation to use for the current platform.
274     */
275    static final MenuVersionImpl IMPL;
276    static {
277        if (BuildCompat.isAtLeastO()) {
278            IMPL = new MenuItemCompatApi26Impl();
279        } else {
280            IMPL = new MenuItemCompatBaseImpl();
281        }
282    }
283
284    // -------------------------------------------------------------------
285
286    /**
287     * Sets how this item should display in the presence of a compatible Action Bar. If the given
288     * item is compatible, this will call the item's supported implementation of
289     * {@link MenuItem#setShowAsAction(int)}.
290     *
291     * @param item - the item to change
292     * @param actionEnum - How the item should display.
293     *
294     * @deprecated Use {@link MenuItem#setShowAsAction(int)} directly.
295     */
296    @Deprecated
297    public static void setShowAsAction(MenuItem item, int actionEnum) {
298        item.setShowAsAction(actionEnum);
299    }
300
301    /**
302     * Set an action view for this menu item. An action view will be displayed in place
303     * of an automatically generated menu item element in the UI when this item is shown
304     * as an action within a parent.
305     *
306     * @param item the item to change
307     * @param view View to use for presenting this item to the user.
308     * @return This Item so additional setters can be called.
309     *
310     * @see #setShowAsAction(MenuItem, int)
311     *
312     * @deprecated Use {@link MenuItem#setActionView(View)} directly.
313     */
314    @Deprecated
315    public static MenuItem setActionView(MenuItem item, View view) {
316        return item.setActionView(view);
317    }
318
319    /**
320     * Set an action view for this menu item. An action view will be displayed in place
321     * of an automatically generated menu item element in the UI when this item is shown
322     * as an action within a parent.
323     * <p>
324     *   <strong>Note:</strong> Setting an action view overrides the action provider
325     *           set via {@link #setActionProvider(MenuItem, ActionProvider)}.
326     * </p>
327     *
328     * @param item the item to change
329     * @param resId Layout resource to use for presenting this item to the user.
330     * @return This Item so additional setters can be called.
331     *
332     * @see #setShowAsAction(MenuItem, int)
333     *
334     * @deprecated Use {@link MenuItem#setActionView(int)} directly.
335     */
336    @Deprecated
337    public static MenuItem setActionView(MenuItem item, int resId) {
338        return item.setActionView(resId);
339    }
340
341    /**
342     * Returns the currently set action view for this menu item.
343     *
344     * @param item the item to query
345     * @return This item's action view
346     *
347     * @deprecated Use {@link MenuItem#getActionView()} directly.
348     */
349    @Deprecated
350    public static View getActionView(MenuItem item) {
351        return item.getActionView();
352    }
353
354    /**
355     * Sets the {@link ActionProvider} responsible for creating an action view if
356     * the item is placed on the action bar. The provider also provides a default
357     * action invoked if the item is placed in the overflow menu.
358     * <p>
359     *   <strong>Note:</strong> Setting an action provider overrides the action view
360     *           set via {@link #setActionView(MenuItem, View)}.
361     * </p>
362     *
363     * @param item item to change
364     * @param provider The action provider.
365     * @return This Item so additional setters can be called.
366     *
367     * @see ActionProvider
368     */
369    public static MenuItem setActionProvider(MenuItem item, ActionProvider provider) {
370        if (item instanceof SupportMenuItem) {
371            return ((SupportMenuItem) item).setSupportActionProvider(provider);
372        }
373        // TODO Wrap the support ActionProvider and assign it
374        Log.w(TAG, "setActionProvider: item does not implement SupportMenuItem; ignoring");
375        return item;
376    }
377
378    /**
379     * Gets the {@link ActionProvider}.
380     *
381     * @return The action provider.
382     *
383     * @see ActionProvider
384     * @see #setActionProvider(MenuItem, ActionProvider)
385     */
386    public static ActionProvider getActionProvider(MenuItem item) {
387        if (item instanceof SupportMenuItem) {
388            return ((SupportMenuItem) item).getSupportActionProvider();
389        }
390
391        // TODO Wrap the framework ActionProvider and return it
392        Log.w(TAG, "getActionProvider: item does not implement SupportMenuItem; returning null");
393        return null;
394    }
395
396    /**
397     * Expand the action view associated with this menu item.
398     * The menu item must have an action view set, as well as
399     * the showAsAction flag {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}.
400     * If a listener has been set using
401     * {@link #setOnActionExpandListener(MenuItem, OnActionExpandListener)}
402     * it will have its {@link OnActionExpandListener#onMenuItemActionExpand(MenuItem)}
403     * method invoked. The listener may return false from this method to prevent expanding
404     * the action view.
405     *
406     * @return true if the action view was expanded, false otherwise.
407     *
408     * @deprecated Use {@link MenuItem#expandActionView()} directly.
409     */
410    @Deprecated
411    public static boolean expandActionView(MenuItem item) {
412        return item.expandActionView();
413    }
414
415    /**
416     * Collapse the action view associated with this menu item. The menu item must have an action
417     * view set, as well as the showAsAction flag {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}. If a
418     * listener has been set using {@link #setOnActionExpandListener(MenuItem,
419     * android.support.v4.view.MenuItemCompat.OnActionExpandListener)}
420     * it will have its {@link
421     * android.support.v4.view.MenuItemCompat.OnActionExpandListener#onMenuItemActionCollapse(MenuItem)}
422     * method invoked. The listener may return false from this method to prevent collapsing
423     * the action view.
424     *
425     * @return true if the action view was collapsed, false otherwise.
426     *
427     * @deprecated Use {@link MenuItem#collapseActionView()} directly.
428     */
429    @Deprecated
430    public static boolean collapseActionView(MenuItem item) {
431        return item.collapseActionView();
432    }
433
434    /**
435     * Returns true if this menu item's action view has been expanded.
436     *
437     * @return true if the item's action view is expanded, false otherwise.
438     * @see #expandActionView(MenuItem)
439     * @see #collapseActionView(MenuItem)
440     * @see #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW
441     * @see android.support.v4.view.MenuItemCompat.OnActionExpandListener
442     *
443     * @deprecated Use {@link MenuItem#isActionViewExpanded()} directly.
444     */
445    @Deprecated
446    public static boolean isActionViewExpanded(MenuItem item) {
447        return item.isActionViewExpanded();
448    }
449
450    /**
451     * Set an {@link OnActionExpandListener} on this menu
452     * item to be notified when the associated action view is expanded or collapsed.
453     * The menu item must be configured to expand or collapse its action view using the flag
454     * {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}.
455     *
456     * @param listener Listener that will respond to expand/collapse events
457     * @return This menu item instance for call chaining
458     *
459     * @deprecated Use {@link MenuItem#setOnActionExpandListener(MenuItem.OnActionExpandListener)}
460     * directly.
461     */
462    @Deprecated
463    public static MenuItem setOnActionExpandListener(MenuItem item,
464            final OnActionExpandListener listener) {
465        return item.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
466            @Override
467            public boolean onMenuItemActionExpand(MenuItem item) {
468                return listener.onMenuItemActionExpand(item);
469            }
470
471            @Override
472            public boolean onMenuItemActionCollapse(MenuItem item) {
473                return listener.onMenuItemActionCollapse(item);
474            }
475        });
476    }
477
478    /**
479     * Change the content description associated with this menu item.
480     *
481     * @param item item to change.
482     * @param contentDescription The new content description.
483     */
484    public static void setContentDescription(MenuItem item, CharSequence contentDescription) {
485        if (item instanceof SupportMenuItem) {
486            ((SupportMenuItem) item).setContentDescription(contentDescription);
487        } else {
488            IMPL.setContentDescription(item, contentDescription);
489        }
490    }
491
492    /**
493     * Retrieve the content description associated with this menu item.
494     *
495     * @return The content description.
496     */
497    public static CharSequence getContentDescription(MenuItem item) {
498        if (item instanceof SupportMenuItem) {
499            return ((SupportMenuItem) item).getContentDescription();
500        }
501        return IMPL.getContentDescription(item);
502    }
503
504    /**
505     * Change the tooltip text associated with this menu item.
506     *
507     * @param item item to change.
508     * @param tooltipText The new tooltip text
509     */
510    public static void setTooltipText(MenuItem item, CharSequence tooltipText) {
511        if (item instanceof SupportMenuItem) {
512            ((SupportMenuItem) item).setTooltipText(tooltipText);
513        } else {
514            IMPL.setTooltipText(item, tooltipText);
515        }
516    }
517
518    /**
519     * Retrieve the tooltip text associated with this menu item.
520     *
521     * @return The tooltip text.
522     */
523    public static CharSequence getTooltipText(MenuItem item) {
524        if (item instanceof SupportMenuItem) {
525            return ((SupportMenuItem) item).getTooltipText();
526        }
527        return IMPL.getTooltipText(item);
528    }
529
530    /**
531     * Change both the numeric and alphabetic shortcut associated with this
532     * item. Note that the shortcut will be triggered when the key that
533     * generates the given character is pressed along with the corresponding
534     * modifier key. Also note that case is not significant and that alphabetic
535     * shortcut characters will be handled in lower case.
536     * <p>
537     * See {@link Menu} for the menu types that support shortcuts.
538     *
539     * @param numericChar The numeric shortcut key. This is the shortcut when
540     *        using a numeric (e.g., 12-key) keyboard.
541     * @param numericModifiers The numeric modifier associated with the shortcut. It should
542     *        be a combination of {@link KeyEvent#META_META_ON}, {@link KeyEvent#META_CTRL_ON},
543     *        {@link KeyEvent#META_ALT_ON}, {@link KeyEvent#META_SHIFT_ON},
544     *        {@link KeyEvent#META_SYM_ON}, {@link KeyEvent#META_FUNCTION_ON}.
545     * @param alphaChar The alphabetic shortcut key. This is the shortcut when
546     *        using a keyboard with alphabetic keys.
547     * @param alphaModifiers The alphabetic modifier associated with the shortcut. It should
548     *        be a combination of {@link KeyEvent#META_META_ON}, {@link KeyEvent#META_CTRL_ON},
549     *        {@link KeyEvent#META_ALT_ON}, {@link KeyEvent#META_SHIFT_ON},
550     *        {@link KeyEvent#META_SYM_ON}, {@link KeyEvent#META_FUNCTION_ON}.
551     */
552    public static void setShortcut(MenuItem item, char numericChar, char alphaChar,
553            int numericModifiers, int alphaModifiers) {
554        if (item instanceof SupportMenuItem) {
555            ((SupportMenuItem) item).setShortcut(numericChar, alphaChar, numericModifiers,
556                    alphaModifiers);
557        } else {
558            IMPL.setShortcut(item, numericChar, alphaChar, numericModifiers, alphaModifiers);
559        }
560    }
561
562    /**
563     * Change the numeric shortcut and modifiers associated with this item.
564     * <p>
565     * See {@link Menu} for the menu types that support shortcuts.
566     *
567     * @param numericChar The numeric shortcut key.  This is the shortcut when
568     *                 using a 12-key (numeric) keyboard.
569     * @param numericModifiers The modifier associated with the shortcut. It should
570     *        be a combination of {@link KeyEvent#META_META_ON}, {@link KeyEvent#META_CTRL_ON},
571     *        {@link KeyEvent#META_ALT_ON}, {@link KeyEvent#META_SHIFT_ON},
572     *        {@link KeyEvent#META_SYM_ON}, {@link KeyEvent#META_FUNCTION_ON}.
573     */
574    public static void setNumericShortcut(MenuItem item, char numericChar, int numericModifiers) {
575        if (item instanceof SupportMenuItem) {
576            ((SupportMenuItem) item).setNumericShortcut(numericChar, numericModifiers);
577        } else {
578            IMPL.setNumericShortcut(item, numericChar, numericModifiers);
579        }
580    }
581
582    /**
583     * Return the modifiers for this menu item's numeric (12-key) shortcut.
584     * The modifier is a combination of {@link KeyEvent#META_META_ON},
585     * {@link KeyEvent#META_CTRL_ON}, {@link KeyEvent#META_ALT_ON},
586     * {@link KeyEvent#META_SHIFT_ON}, {@link KeyEvent#META_SYM_ON},
587     * {@link KeyEvent#META_FUNCTION_ON}.
588     * For example, {@link KeyEvent#META_FUNCTION_ON}|{@link KeyEvent#META_CTRL_ON}
589     *
590     * @return Modifier associated with the numeric shortcut.
591     */
592    public static int getNumericModifiers(MenuItem item) {
593        if (item instanceof SupportMenuItem) {
594            return ((SupportMenuItem) item).getNumericModifiers();
595        }
596        return IMPL.getNumericModifiers(item);
597    }
598
599    /**
600     * Change the alphabetic shortcut associated with this item. The shortcut
601     * will be triggered when the key that generates the given character is
602     * pressed along with the modifier keys. Case is not significant and shortcut
603     * characters will be displayed in lower case. Note that menu items with
604     * the characters '\b' or '\n' as shortcuts will get triggered by the
605     * Delete key or Carriage Return key, respectively.
606     * <p>
607     * See {@link Menu} for the menu types that support shortcuts.
608     *
609     * @param alphaChar The alphabetic shortcut key. This is the shortcut when
610     *        using a keyboard with alphabetic keys.
611     * @param alphaModifiers The modifier associated with the shortcut. It should
612     *        be a combination of {@link KeyEvent#META_META_ON}, {@link KeyEvent#META_CTRL_ON},
613     *        {@link KeyEvent#META_ALT_ON}, {@link KeyEvent#META_SHIFT_ON},
614     *        {@link KeyEvent#META_SYM_ON}, {@link KeyEvent#META_FUNCTION_ON}.
615     */
616    public static void setAlphabeticShortcut(MenuItem item, char alphaChar, int alphaModifiers) {
617        if (item instanceof SupportMenuItem) {
618            ((SupportMenuItem) item).setAlphabeticShortcut(alphaChar, alphaModifiers);
619        } else {
620            IMPL.setAlphabeticShortcut(item, alphaChar, alphaModifiers);
621        }
622    }
623
624    /**
625     * Return the modifier for this menu item's alphabetic shortcut.
626     * The modifier is a combination of {@link KeyEvent#META_META_ON},
627     * {@link KeyEvent#META_CTRL_ON}, {@link KeyEvent#META_ALT_ON},
628     * {@link KeyEvent#META_SHIFT_ON}, {@link KeyEvent#META_SYM_ON},
629     * {@link KeyEvent#META_FUNCTION_ON}.
630     * For example, {@link KeyEvent#META_FUNCTION_ON}|{@link KeyEvent#META_CTRL_ON}
631     *
632     * @return Modifier associated with the keyboard shortcut.
633     */
634    public static int getAlphabeticModifiers(MenuItem item) {
635        if (item instanceof SupportMenuItem) {
636            return ((SupportMenuItem) item).getAlphabeticModifiers();
637        }
638        return IMPL.getAlphabeticModifiers(item);
639    }
640
641    /**
642     * Applies a tint to the item's icon. Does not modify the
643     * current tint mode of that item, which is {@link PorterDuff.Mode#SRC_IN} by default.
644     * <p>
645     * Subsequent calls to {@link MenuItem#setIcon(Drawable)} or {@link MenuItem#setIcon(int)} will
646     * automatically mutate the icon and apply the specified tint and
647     * tint mode.
648     *
649     * @param tint the tint to apply, may be {@code null} to clear tint
650     *
651     * @see #getIconTintList(MenuItem)
652     */
653    public static void setIconTintList(MenuItem item, ColorStateList tint) {
654        if (item instanceof SupportMenuItem) {
655            ((SupportMenuItem) item).setIconTintList(tint);
656        } else {
657            IMPL.setIconTintList(item, tint);
658        }
659    }
660
661    /**
662     * @return the tint applied to the item's icon
663     * @see #setIconTintList(MenuItem, ColorStateList)
664     */
665    public static ColorStateList getIconTintList(MenuItem item) {
666        if (item instanceof SupportMenuItem) {
667            return ((SupportMenuItem) item).getIconTintList();
668        }
669        return IMPL.getIconTintList(item);
670    }
671
672    /**
673     * Specifies the blending mode used to apply the tint specified by
674     * {@link #setIconTintList(MenuItem, ColorStateList)} to the item's icon. The default mode is
675     * {@link PorterDuff.Mode#SRC_IN}.
676     *
677     * @param tintMode the blending mode used to apply the tint, may be
678     *                 {@code null} to clear tint
679     * @see #setIconTintList(MenuItem, ColorStateList)
680     */
681    public static void setIconTintMode(MenuItem item, PorterDuff.Mode tintMode) {
682        if (item instanceof SupportMenuItem) {
683            ((SupportMenuItem) item).setIconTintMode(tintMode);
684        } else {
685            IMPL.setIconTintMode(item, tintMode);
686        }
687    }
688
689    /**
690     * Returns the blending mode used to apply the tint to the item's icon, if specified.
691     *
692     * @return the blending mode used to apply the tint to the item's icon
693     * @see #setIconTintMode(MenuItem, PorterDuff.Mode)
694     */
695    public static PorterDuff.Mode getIconTintMode(MenuItem item) {
696        if (item instanceof SupportMenuItem) {
697            return ((SupportMenuItem) item).getIconTintMode();
698        }
699        return IMPL.getIconTintMode(item);
700    }
701
702    private MenuItemCompat() {}
703}
704