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