NavigationMenuPresenter.java revision 153fa9a03422419cd56b7d17def1ae907fc7b5cf
131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki/*
231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * Copyright (C) 2015 The Android Open Source Project
331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki *
431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * Licensed under the Apache License, Version 2.0 (the "License");
531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * you may not use this file except in compliance with the License.
631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * You may obtain a copy of the License at
731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki *
831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki *      http://www.apache.org/licenses/LICENSE-2.0
931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki *
1031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * Unless required by applicable law or agreed to in writing, software
1131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * distributed under the License is distributed on an "AS IS" BASIS,
1231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * See the License for the specific language governing permissions and
1431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * limitations under the License.
1531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki */
1631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
1731a49efe2adb59e31611f6871895a3243d835127Yuichi Arakipackage android.support.design.internal;
1831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
1931a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.content.Context;
20d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Arakiimport android.content.res.ColorStateList;
2160abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Arakiimport android.content.res.Resources;
228bc6f4dfa590d8cd872a9894804a4c80d01a5d87Yuichi Arakiimport android.graphics.drawable.ColorDrawable;
23a63940ca14cd3ad9620e94f709930bb968525c57Chris Banesimport android.graphics.drawable.Drawable;
2401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Arakiimport android.os.Bundle;
2531a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.os.Parcelable;
2601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Arakiimport android.support.annotation.LayoutRes;
2701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Arakiimport android.support.annotation.NonNull;
28d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Arakiimport android.support.annotation.Nullable;
29153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banesimport android.support.annotation.StyleRes;
3031a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.support.design.R;
3131a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.support.v7.internal.view.menu.MenuBuilder;
3231a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.support.v7.internal.view.menu.MenuItemImpl;
3331a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.support.v7.internal.view.menu.MenuPresenter;
3431a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.support.v7.internal.view.menu.MenuView;
3531a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.support.v7.internal.view.menu.SubMenuBuilder;
3601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Arakiimport android.util.SparseArray;
3731a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.view.LayoutInflater;
3801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Arakiimport android.view.MenuItem;
3901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Arakiimport android.view.SubMenu;
4031a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.view.View;
4131a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.view.ViewGroup;
4231a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.widget.AdapterView;
4331a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.widget.BaseAdapter;
4472fa50f289d462aae5038e8dd78e134a0fffcf12Yuichi Arakiimport android.widget.LinearLayout;
4501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Arakiimport android.widget.TextView;
4601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki
4701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Arakiimport java.util.ArrayList;
4831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
4931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki/**
5031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * @hide
5131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki */
5231a49efe2adb59e31611f6871895a3243d835127Yuichi Arakipublic class NavigationMenuPresenter implements MenuPresenter, AdapterView.OnItemClickListener {
5331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
5401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki    private static final String STATE_HIERARCHY = "android:menu:list";
5576bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki    private static final String STATE_ADAPTER = "android:menu:adapter";
5601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki
5731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    private NavigationMenuView mMenuView;
5872fa50f289d462aae5038e8dd78e134a0fffcf12Yuichi Araki    private LinearLayout mHeader;
5931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
6031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    private Callback mCallback;
6131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    private MenuBuilder mMenu;
6231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    private int mId;
6331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
6431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    private NavigationMenuAdapter mAdapter;
6531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    private LayoutInflater mLayoutInflater;
6631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
67153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes    private int mTextAppearance;
68153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes    private boolean mTextAppearanceSet;
69a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes    private ColorStateList mTextColor;
70a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes    private ColorStateList mIconTintList;
71a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes    private Drawable mItemBackground;
72d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki
7301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki    /**
7401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki     * Padding to be inserted at the top of the list to avoid the first menu item
7501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki     * from being placed underneath the status bar.
7601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki     */
7701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki    private int mPaddingTopDefault;
7801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki
7960abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki    /**
8060abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki     * Padding for separators between items
8160abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki     */
8260abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki    private int mPaddingSeparator;
8360abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki
8431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    @Override
8531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    public void initForMenu(Context context, MenuBuilder menu) {
8631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        mLayoutInflater = LayoutInflater.from(context);
8731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        mMenu = menu;
8860abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki        Resources res = context.getResources();
8960abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki        mPaddingTopDefault = res.getDimensionPixelOffset(R.dimen.navigation_padding_top_default);
9060abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki        mPaddingSeparator = res.getDimensionPixelOffset(
9160abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki                R.dimen.navigation_separator_vertical_padding);
9231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
9331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
9431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    @Override
9531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    public MenuView getMenuView(ViewGroup root) {
9631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        if (mMenuView == null) {
9731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mMenuView = (NavigationMenuView) mLayoutInflater.inflate(
98a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki                    R.layout.design_navigation_menu, root, false);
9931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            if (mAdapter == null) {
10031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki                mAdapter = new NavigationMenuAdapter();
10131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            }
10272fa50f289d462aae5038e8dd78e134a0fffcf12Yuichi Araki            mHeader = (LinearLayout) mLayoutInflater.inflate(R.layout.design_navigation_item_header,
10372fa50f289d462aae5038e8dd78e134a0fffcf12Yuichi Araki                    mMenuView, false);
10472fa50f289d462aae5038e8dd78e134a0fffcf12Yuichi Araki            mMenuView.addHeaderView(mHeader);
10531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mMenuView.setAdapter(mAdapter);
10631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mMenuView.setOnItemClickListener(this);
10731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        }
10831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        return mMenuView;
10931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
11031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
11131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    @Override
11231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    public void updateMenuView(boolean cleared) {
11331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        if (mAdapter != null) {
11431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mAdapter.notifyDataSetChanged();
11531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        }
11631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
11731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
11831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    @Override
11931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    public void setCallback(Callback cb) {
12031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        mCallback = cb;
12131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
12231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
12331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    @Override
12431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
12531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        return false;
12631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
12731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
12831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    @Override
12931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
13031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        if (mCallback != null) {
13131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            mCallback.onCloseMenu(menu, allMenusAreClosing);
13231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        }
13331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
13431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
13531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    @Override
13631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    public boolean flagActionItems() {
13731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        return false;
13831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
13931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
14031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    @Override
14131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) {
14231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        return false;
14331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
14431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
14531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    @Override
14631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) {
14731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        return false;
14831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
14931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
15031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    @Override
15131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    public int getId() {
15231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        return mId;
15331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
15431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
15531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    public void setId(int id) {
15631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        mId = id;
15731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
15831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
15931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    @Override
16031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    public Parcelable onSaveInstanceState() {
16101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        Bundle state = new Bundle();
16201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        if (mMenuView != null) {
16376bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki            SparseArray<Parcelable> hierarchy = new SparseArray<>();
16401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki            mMenuView.saveHierarchyState(hierarchy);
16576bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki            state.putSparseParcelableArray(STATE_HIERARCHY, hierarchy);
16676bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki        }
16776bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki        if (mAdapter != null) {
16876bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki            state.putBundle(STATE_ADAPTER, mAdapter.createInstanceState());
16901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        }
17001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        return state;
17131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
17231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
17331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    @Override
17401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki    public void onRestoreInstanceState(Parcelable parcelable) {
17501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        Bundle state = (Bundle) parcelable;
17601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        SparseArray<Parcelable> hierarchy = state.getSparseParcelableArray(STATE_HIERARCHY);
17701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        if (hierarchy != null) {
17801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki            mMenuView.restoreHierarchyState(hierarchy);
17901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        }
18076bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki        Bundle adapterState = state.getBundle(STATE_ADAPTER);
18176bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki        if (adapterState != null) {
18276bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki            mAdapter.restoreInstanceState(adapterState);
18376bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki        }
18431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
18531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
18631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    @Override
18731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
18801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        int positionInAdapter = position - mMenuView.getHeaderViewsCount();
18901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        if (positionInAdapter >= 0) {
190f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki            setUpdateSuspended(true);
191f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki            MenuItemImpl item = mAdapter.getItem(positionInAdapter).getMenuItem();
192f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki            if (item != null && item.isCheckable()) {
193f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki                setCheckedItem(item);
194f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki            }
195f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki            mMenu.performItemAction(item, this, 0);
196f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki            setUpdateSuspended(false);
197f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki            updateMenuView(false);
19801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        }
19901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki    }
20001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki
201f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki    public void setCheckedItem(MenuItemImpl item) {
202f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki        mAdapter.setCheckedItem(item);
203f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki    }
204f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki
20501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki    public View inflateHeaderView(@LayoutRes int res) {
20672fa50f289d462aae5038e8dd78e134a0fffcf12Yuichi Araki        View view = mLayoutInflater.inflate(res, mHeader, false);
20701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        addHeaderView(view);
20801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        return view;
20901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki    }
21001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki
21101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki    public void addHeaderView(@NonNull View view) {
21272fa50f289d462aae5038e8dd78e134a0fffcf12Yuichi Araki        mHeader.addView(view);
21301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        // The padding on top should be cleared.
21460abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki        mMenuView.setPadding(0, 0, 0, mMenuView.getPaddingBottom());
21501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki    }
21601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki
21701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki    public void removeHeaderView(@NonNull View view) {
21872fa50f289d462aae5038e8dd78e134a0fffcf12Yuichi Araki        mHeader.removeView(view);
21972fa50f289d462aae5038e8dd78e134a0fffcf12Yuichi Araki        if (mHeader.getChildCount() == 0) {
22072fa50f289d462aae5038e8dd78e134a0fffcf12Yuichi Araki            mMenuView.setPadding(0, mPaddingTopDefault, 0, mMenuView.getPaddingBottom());
22101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        }
22231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
22331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
224d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki    @Nullable
225d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki    public ColorStateList getItemTintList() {
226a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes        return mIconTintList;
227d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki    }
228d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki
229a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes    public void setItemIconTintList(@Nullable ColorStateList tint) {
230a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes        mIconTintList = tint;
231153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes        updateMenuView(false);
232d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki    }
233d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki
234a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes    @Nullable
235a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes    public ColorStateList getItemTextColor() {
236a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes        return mTextColor;
237a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes    }
238a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes
239a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes    public void setItemTextColor(@Nullable ColorStateList textColor) {
240a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes        mTextColor = textColor;
241153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes        updateMenuView(false);
242153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes    }
243153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes
244153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes    public void setItemTextAppearance(@StyleRes int resId) {
245153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes        mTextAppearance = resId;
246153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes        mTextAppearanceSet = true;
247153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes        updateMenuView(false);
248a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes    }
249a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes
250a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes    public Drawable getItemBackground() {
251a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes        return mItemBackground;
252d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki    }
253d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki
254a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes    public void setItemBackground(Drawable itemBackground) {
255a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes        mItemBackground = itemBackground;
256d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki    }
257d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki
258cc7a09fc0018e348027151daecf581b1d1b78f11Yuichi Araki    public void setUpdateSuspended(boolean updateSuspended) {
259cc7a09fc0018e348027151daecf581b1d1b78f11Yuichi Araki        if (mAdapter != null) {
260cc7a09fc0018e348027151daecf581b1d1b78f11Yuichi Araki            mAdapter.setUpdateSuspended(updateSuspended);
261cc7a09fc0018e348027151daecf581b1d1b78f11Yuichi Araki        }
262cc7a09fc0018e348027151daecf581b1d1b78f11Yuichi Araki    }
263cc7a09fc0018e348027151daecf581b1d1b78f11Yuichi Araki
26431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    private class NavigationMenuAdapter extends BaseAdapter {
26576bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki
266f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki        private static final String STATE_CHECKED_ITEM = "android:menu:checked";
26776bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki
26801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        private static final int VIEW_TYPE_NORMAL = 0;
26901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        private static final int VIEW_TYPE_SUBHEADER = 1;
27001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        private static final int VIEW_TYPE_SEPARATOR = 2;
27101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki
2723a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes        private final ArrayList<NavigationMenuItem> mItems = new ArrayList<>();
273f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki        private MenuItemImpl mCheckedItem;
2743a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes        private ColorDrawable mTransparentIcon;
27576bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki        private boolean mUpdateSuspended;
2763a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes
2773a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes        NavigationMenuAdapter() {
2783a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes            prepareMenuItems();
2793a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes        }
2803a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes
28131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        @Override
28231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        public int getCount() {
28301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki            return mItems.size();
28431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        }
28531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
28631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        @Override
28701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        public NavigationMenuItem getItem(int position) {
28801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki            return mItems.get(position);
28931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        }
29031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
29131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        @Override
29231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        public long getItemId(int position) {
29331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            return position;
29431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        }
29531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
29631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        @Override
29701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        public int getViewTypeCount() {
29801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki            return 3;
29901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        }
30001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki
30101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        @Override
30201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        public int getItemViewType(int position) {
30301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki            NavigationMenuItem item = getItem(position);
30401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki            if (item.isSeparator()) {
30501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki                return VIEW_TYPE_SEPARATOR;
30601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki            } else if (item.getMenuItem().hasSubMenu()) {
30701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki                return VIEW_TYPE_SUBHEADER;
30801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki            } else {
30901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki                return VIEW_TYPE_NORMAL;
31001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki            }
31101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        }
31201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki
31301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        @Override
31431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        public View getView(int position, View convertView, ViewGroup parent) {
31501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki            NavigationMenuItem item = getItem(position);
31601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki            int viewType = getItemViewType(position);
31701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki            switch (viewType) {
31801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki                case VIEW_TYPE_NORMAL:
31901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki                    if (convertView == null) {
320a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki                        convertView = mLayoutInflater.inflate(R.layout.design_navigation_item,
321a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki                                parent, false);
32201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki                    }
323d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki                    NavigationMenuItemView itemView = (NavigationMenuItemView) convertView;
324a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes                    itemView.setIconTintList(mIconTintList);
325153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes                    if (mTextAppearanceSet) {
326153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes                        itemView.setTextAppearance(itemView.getContext(), mTextAppearance);
327153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes                    }
328153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes                    if (mTextColor != null) {
329153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes                        itemView.setTextColor(mTextColor);
330153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes                    }
33144dc3d86d8fa6544d49b2e14f89c9b1f49639dbdChris Banes                    itemView.setBackgroundDrawable(mItemBackground);
33201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki                    itemView.initialize(item.getMenuItem(), 0);
33301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki                    break;
33401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki                case VIEW_TYPE_SUBHEADER:
33501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki                    if (convertView == null) {
336a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki                        convertView = mLayoutInflater.inflate(
337a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki                                R.layout.design_navigation_item_subheader, parent, false);
33801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki                    }
33901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki                    TextView subHeader = (TextView) convertView;
34001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki                    subHeader.setText(item.getMenuItem().getTitle());
34101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki                    break;
34201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki                case VIEW_TYPE_SEPARATOR:
34301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki                    if (convertView == null) {
344a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki                        convertView = mLayoutInflater.inflate(
345a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki                                R.layout.design_navigation_item_separator, parent, false);
34601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki                    }
34760abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki                    convertView.setPadding(0, item.getPaddingTop(), 0,
34860abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki                            item.getPaddingBottom());
34901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki                    break;
35031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            }
35131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki            return convertView;
35231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki        }
35301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki
35401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        @Override
35501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        public boolean areAllItemsEnabled() {
35601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki            return false;
35701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        }
35801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki
35901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        @Override
36001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        public boolean isEnabled(int position) {
36101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki            return getItem(position).isEnabled();
36201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        }
36301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki
3643a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes        @Override
3653a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes        public void notifyDataSetChanged() {
3663a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes            prepareMenuItems();
3673a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes            super.notifyDataSetChanged();
3683a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes        }
3693a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes
3703a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes        /**
3713a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes         * Flattens the visible menu items of {@link #mMenu} into {@link #mItems},
3723a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes         * while inserting separators between items when necessary.
3733a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes         */
3743a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes        private void prepareMenuItems() {
37576bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki            if (mUpdateSuspended) {
37676bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki                return;
37776bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki            }
3783a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes            mItems.clear();
3793a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes            int currentGroupId = -1;
3803a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes            int currentGroupStart = 0;
3813a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes            boolean currentGroupHasIcon = false;
3823a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes            for (int i = 0, totalSize = mMenu.getVisibleItems().size(); i < totalSize; i++) {
3833a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                MenuItemImpl item = mMenu.getVisibleItems().get(i);
384f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki                if (item.isChecked()) {
385f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki                    setCheckedItem(item);
386f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki                }
387f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki                if (item.isCheckable()) {
388f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki                    item.setExclusiveCheckable(false);
389f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki                }
3903a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                if (item.hasSubMenu()) {
3913a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                    SubMenu subMenu = item.getSubMenu();
3923a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                    if (subMenu.hasVisibleItems()) {
3933a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                        if (i != 0) {
39460abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki                            mItems.add(NavigationMenuItem.separator(mPaddingSeparator, 0));
3953a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                        }
3963a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                        mItems.add(NavigationMenuItem.of(item));
3973a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                        boolean subMenuHasIcon = false;
3983a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                        int subMenuStart = mItems.size();
3993a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                        for (int j = 0, size = subMenu.size(); j < size; j++) {
400f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki                            MenuItemImpl subMenuItem = (MenuItemImpl) subMenu.getItem(j);
4013a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                            if (subMenuItem.isVisible()) {
4023a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                                if (!subMenuHasIcon && subMenuItem.getIcon() != null) {
4033a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                                    subMenuHasIcon = true;
4043a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                                }
405f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki                                if (subMenuItem.isCheckable()) {
406f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki                                    subMenuItem.setExclusiveCheckable(false);
407f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki                                }
408f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki                                if (item.isChecked()) {
409f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki                                    setCheckedItem(item);
410f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki                                }
411f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki                                mItems.add(NavigationMenuItem.of(subMenuItem));
4123a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                            }
4133a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                        }
4143a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                        if (subMenuHasIcon) {
4153a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                            appendTransparentIconIfMissing(subMenuStart, mItems.size());
4163a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                        }
4173a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                    }
4183a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                } else {
4193a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                    int groupId = item.getGroupId();
4203a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                    if (groupId != currentGroupId) { // first item in group
4213a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                        currentGroupStart = mItems.size();
4223a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                        currentGroupHasIcon = item.getIcon() != null;
4233a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                        if (i != 0) {
4243a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                            currentGroupStart++;
42560abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki                            mItems.add(NavigationMenuItem.separator(
42660abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki                                    mPaddingSeparator, mPaddingSeparator));
4273a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                        }
4283a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                    } else if (!currentGroupHasIcon && item.getIcon() != null) {
4293a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                        currentGroupHasIcon = true;
4303a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                        appendTransparentIconIfMissing(currentGroupStart, mItems.size());
4313a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                    }
4323a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                    if (currentGroupHasIcon && item.getIcon() == null) {
4333a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                        item.setIcon(android.R.color.transparent);
4343a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                    }
4353a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                    mItems.add(NavigationMenuItem.of(item));
4363a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                    currentGroupId = groupId;
4373a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                }
4383a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes            }
4393a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes        }
4403a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes
4413a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes        private void appendTransparentIconIfMissing(int startIndex, int endIndex) {
4423a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes            for (int i = startIndex; i < endIndex; i++) {
4433a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                MenuItem item = mItems.get(i).getMenuItem();
4443a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                if (item.getIcon() == null) {
4453a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                    if (mTransparentIcon == null) {
4463a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                        mTransparentIcon = new ColorDrawable(android.R.color.transparent);
4473a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                    }
4483a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                    item.setIcon(mTransparentIcon);
4493a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes                }
4503a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes            }
4513a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes        }
45276bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki
453f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki        public void setCheckedItem(MenuItemImpl checkedItem) {
454f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki            if (mCheckedItem == checkedItem || !checkedItem.isCheckable()) {
455f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki                return;
456f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki            }
457f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki            if (mCheckedItem != null) {
458f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki                mCheckedItem.setChecked(false);
459f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki            }
460f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki            mCheckedItem = checkedItem;
461f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki            checkedItem.setChecked(true);
462f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki        }
463f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki
46476bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki        public Bundle createInstanceState() {
46576bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki            Bundle state = new Bundle();
466f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki            state.putInt(STATE_CHECKED_ITEM, mCheckedItem.getItemId());
46776bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki            return state;
46876bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki        }
46976bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki
47076bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki        public void restoreInstanceState(Bundle state) {
471f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki            int checkedItem = state.getInt(STATE_CHECKED_ITEM, 0);
472f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki            if (checkedItem != 0) {
47376bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki                mUpdateSuspended = true;
47476bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki                for (NavigationMenuItem item : mItems) {
47576bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki                    MenuItemImpl menuItem = item.getMenuItem();
476f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki                    if (menuItem !=  null && menuItem.getItemId() == checkedItem) {
477f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki                        setCheckedItem(menuItem);
478f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki                        break;
47976bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki                    }
48076bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki                }
48176bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki                mUpdateSuspended = false;
48276bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki                prepareMenuItems();
48376bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki            }
48476bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki        }
48576bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki
486cc7a09fc0018e348027151daecf581b1d1b78f11Yuichi Araki        public void setUpdateSuspended(boolean updateSuspended) {
487cc7a09fc0018e348027151daecf581b1d1b78f11Yuichi Araki            mUpdateSuspended = updateSuspended;
488cc7a09fc0018e348027151daecf581b1d1b78f11Yuichi Araki        }
489cc7a09fc0018e348027151daecf581b1d1b78f11Yuichi Araki
49001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki    }
49101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki
49201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki    /**
49301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki     * Wraps {@link MenuItemImpl}. This allows separators to be counted as items in list.
49401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki     */
49501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki    private static class NavigationMenuItem {
49601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki
49760abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki        /** The item; null for separators */
49801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        private final MenuItemImpl mMenuItem;
49901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki
50060abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki        /** Padding top; used only for separators */
50160abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki        private final int mPaddingTop;
50260abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki
50360abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki        /** Padding bottom; used only for separators */
50460abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki        private final int mPaddingBottom;
50560abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki
50660abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki        private NavigationMenuItem(MenuItemImpl item, int paddingTop, int paddingBottom) {
50701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki            mMenuItem = item;
50860abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki            mPaddingTop = paddingTop;
50960abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki            mPaddingBottom = paddingBottom;
51001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        }
51101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki
51201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        public static NavigationMenuItem of(MenuItemImpl item) {
51360abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki            return new NavigationMenuItem(item, 0, 0);
51460abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki        }
51560abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki
51660abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki        public static NavigationMenuItem separator(int paddingTop, int paddingBottom) {
51760abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki            return new NavigationMenuItem(null, paddingTop, paddingBottom);
51801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        }
51901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki
52001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        public boolean isSeparator() {
52160abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki            return mMenuItem == null;
52260abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki        }
52360abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki
52460abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki        public int getPaddingTop() {
52560abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki            return mPaddingTop;
52660abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki        }
52760abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki
52860abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki        public int getPaddingBottom() {
52960abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki            return mPaddingBottom;
53001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        }
53101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki
53201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        public MenuItemImpl getMenuItem() {
53301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki            return mMenuItem;
53401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        }
53501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki
53601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        public boolean isEnabled() {
53701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki            // Separators and subheaders never respond to click
53801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki            return mMenuItem != null && !mMenuItem.hasSubMenu() && mMenuItem.isEnabled();
53901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki        }
54001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki
54131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki    }
54231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki
54331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki}
544