NavigationMenuPresenter.java revision ca2f07c9cc83b98d73a18da7177044ee147ffb94
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; 42ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banesimport android.widget.AdapterView; 43ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banesimport 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 */ 52ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banespublic 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; 58ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes 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(); 89a577676a64e5353b8ec927117151aa6be84adf66Chris Banes mPaddingTopDefault = res.getDimensionPixelOffset( 90a577676a64e5353b8ec927117151aa6be84adf66Chris Banes R.dimen.design_navigation_padding_top_default); 9160abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki mPaddingSeparator = res.getDimensionPixelOffset( 92a577676a64e5353b8ec927117151aa6be84adf66Chris Banes R.dimen.design_navigation_separator_vertical_padding); 9331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 9431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 9531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki @Override 9631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki public MenuView getMenuView(ViewGroup root) { 9731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki if (mMenuView == null) { 9831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki mMenuView = (NavigationMenuView) mLayoutInflater.inflate( 99a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki R.layout.design_navigation_menu, root, false); 10031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki if (mAdapter == null) { 10131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki mAdapter = new NavigationMenuAdapter(); 10231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 103ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes mHeader = (LinearLayout) mLayoutInflater.inflate(R.layout.design_navigation_item_header, 104ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes mMenuView, false); 105ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes mMenuView.addHeaderView(mHeader, null, false); 10631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki mMenuView.setAdapter(mAdapter); 107ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes mMenuView.setOnItemClickListener(this); 10831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 10931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki return mMenuView; 11031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 11131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 11231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki @Override 11331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki public void updateMenuView(boolean cleared) { 11431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki if (mAdapter != null) { 115ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes mAdapter.notifyDataSetChanged(); 11631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 11731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 11831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 11931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki @Override 12031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki public void setCallback(Callback cb) { 12131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki mCallback = cb; 12231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 12331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 12431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki @Override 12531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki public boolean onSubMenuSelected(SubMenuBuilder subMenu) { 12631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki return false; 12731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 12831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 12931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki @Override 13031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { 13131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki if (mCallback != null) { 13231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki mCallback.onCloseMenu(menu, allMenusAreClosing); 13331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 13431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 13531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 13631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki @Override 13731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki public boolean flagActionItems() { 13831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki return false; 13931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 14031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 14131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki @Override 14231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) { 14331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki return false; 14431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 14531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 14631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki @Override 14731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) { 14831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki return false; 14931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 15031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 15131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki @Override 15231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki public int getId() { 15331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki return mId; 15431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 15531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 15631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki public void setId(int id) { 15731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki mId = id; 15831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 15931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 16031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki @Override 16131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki public Parcelable onSaveInstanceState() { 16201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki Bundle state = new Bundle(); 16301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki if (mMenuView != null) { 16476bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki SparseArray<Parcelable> hierarchy = new SparseArray<>(); 16501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki mMenuView.saveHierarchyState(hierarchy); 16676bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki state.putSparseParcelableArray(STATE_HIERARCHY, hierarchy); 16776bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki } 16876bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki if (mAdapter != null) { 16976bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki state.putBundle(STATE_ADAPTER, mAdapter.createInstanceState()); 17001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 17101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki return state; 17231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 17331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 17431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki @Override 17501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki public void onRestoreInstanceState(Parcelable parcelable) { 17601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki Bundle state = (Bundle) parcelable; 17701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki SparseArray<Parcelable> hierarchy = state.getSparseParcelableArray(STATE_HIERARCHY); 17801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki if (hierarchy != null) { 17901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki mMenuView.restoreHierarchyState(hierarchy); 18001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 18176bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki Bundle adapterState = state.getBundle(STATE_ADAPTER); 18276bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki if (adapterState != null) { 18376bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki mAdapter.restoreInstanceState(adapterState); 18476bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki } 18531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 18631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 187ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes @Override 188ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 189ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes int positionInAdapter = position - mMenuView.getHeaderViewsCount(); 190ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes if (positionInAdapter >= 0) { 191ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes setUpdateSuspended(true); 192ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes MenuItemImpl item = mAdapter.getItem(positionInAdapter).getMenuItem(); 193ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes boolean result = mMenu.performItemAction(item, this, 0); 194ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes if (item != null && item.isCheckable() && result) { 195ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes mAdapter.setCheckedItem(item); 196ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes } 197ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes setUpdateSuspended(false); 198ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes updateMenuView(false); 199ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes } 200ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes } 201ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes 202f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki public void setCheckedItem(MenuItemImpl item) { 203f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki mAdapter.setCheckedItem(item); 204f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki } 205f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki 20601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki public View inflateHeaderView(@LayoutRes int res) { 207ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes View view = mLayoutInflater.inflate(res, mHeader, false); 20801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki addHeaderView(view); 20901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki return view; 21001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 21101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 21201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki public void addHeaderView(@NonNull View view) { 213ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes mHeader.addView(view); 21401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki // The padding on top should be cleared. 21560abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki mMenuView.setPadding(0, 0, 0, mMenuView.getPaddingBottom()); 21601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 21701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 21801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki public void removeHeaderView(@NonNull View view) { 219ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes mHeader.removeView(view); 220ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes if (mHeader.getChildCount() == 0) { 22172fa50f289d462aae5038e8dd78e134a0fffcf12Yuichi Araki mMenuView.setPadding(0, mPaddingTopDefault, 0, mMenuView.getPaddingBottom()); 22201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 22331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 22431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 225d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki @Nullable 226d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki public ColorStateList getItemTintList() { 227a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes return mIconTintList; 228d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki } 229d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki 230a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes public void setItemIconTintList(@Nullable ColorStateList tint) { 231a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes mIconTintList = tint; 232153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes updateMenuView(false); 233d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki } 234d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki 235a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes @Nullable 236a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes public ColorStateList getItemTextColor() { 237a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes return mTextColor; 238a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes } 239a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes 240a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes public void setItemTextColor(@Nullable ColorStateList textColor) { 241a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes mTextColor = textColor; 242153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes updateMenuView(false); 243153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes } 244153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes 245153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes public void setItemTextAppearance(@StyleRes int resId) { 246153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes mTextAppearance = resId; 247153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes mTextAppearanceSet = true; 248153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes updateMenuView(false); 249a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes } 250a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes 251a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes public Drawable getItemBackground() { 252a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes return mItemBackground; 253d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki } 254d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki 255a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes public void setItemBackground(Drawable itemBackground) { 256a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes mItemBackground = itemBackground; 257d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki } 258d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki 259cc7a09fc0018e348027151daecf581b1d1b78f11Yuichi Araki public void setUpdateSuspended(boolean updateSuspended) { 260cc7a09fc0018e348027151daecf581b1d1b78f11Yuichi Araki if (mAdapter != null) { 261cc7a09fc0018e348027151daecf581b1d1b78f11Yuichi Araki mAdapter.setUpdateSuspended(updateSuspended); 262cc7a09fc0018e348027151daecf581b1d1b78f11Yuichi Araki } 263cc7a09fc0018e348027151daecf581b1d1b78f11Yuichi Araki } 264cc7a09fc0018e348027151daecf581b1d1b78f11Yuichi Araki 265ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes private class NavigationMenuAdapter extends BaseAdapter { 26676bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki 267f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki private static final String STATE_CHECKED_ITEM = "android:menu:checked"; 26876bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki 26936d347c02fa8da71ccd69634484be8156fa0085bYuichi Araki private static final String STATE_ACTION_VIEWS = "android:menu:action_views"; 27001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki private static final int VIEW_TYPE_NORMAL = 0; 27101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki private static final int VIEW_TYPE_SUBHEADER = 1; 27201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki private static final int VIEW_TYPE_SEPARATOR = 2; 27301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 2743a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes private final ArrayList<NavigationMenuItem> mItems = new ArrayList<>(); 275f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki private MenuItemImpl mCheckedItem; 2763a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes private ColorDrawable mTransparentIcon; 27776bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki private boolean mUpdateSuspended; 2783a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes 2793a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes NavigationMenuAdapter() { 2803a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes prepareMenuItems(); 2813a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } 2823a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes 28331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki @Override 284ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes public int getCount() { 285ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes return mItems.size(); 286ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes } 287ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes 288ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes @Override 289ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes public NavigationMenuItem getItem(int position) { 290ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes return mItems.get(position); 291ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes } 292ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes 293ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes @Override 29431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki public long getItemId(int position) { 29531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki return position; 29631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 29731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 29831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki @Override 299ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes public int getViewTypeCount() { 300ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes return 3; 30101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 30201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 30301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki @Override 30401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki public int getItemViewType(int position) { 305ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes NavigationMenuItem item = getItem(position); 306ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes if (item.isSeparator()) { 30701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki return VIEW_TYPE_SEPARATOR; 308ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes } else if (item.getMenuItem().hasSubMenu()) { 309ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes return VIEW_TYPE_SUBHEADER; 310ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes } else { 311ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes return VIEW_TYPE_NORMAL; 31201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 31301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 31401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 31501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki @Override 316ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes public View getView(int position, View convertView, ViewGroup parent) { 317ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes NavigationMenuItem item = getItem(position); 318ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes int viewType = getItemViewType(position); 31901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki switch (viewType) { 32001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki case VIEW_TYPE_NORMAL: 321ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes if (convertView == null) { 322ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes convertView = mLayoutInflater.inflate(R.layout.design_navigation_item, 323ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes parent, false); 324ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes } 325ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes NavigationMenuItemView itemView = (NavigationMenuItemView) convertView; 326a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes itemView.setIconTintList(mIconTintList); 327153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes if (mTextAppearanceSet) { 328153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes itemView.setTextAppearance(itemView.getContext(), mTextAppearance); 329153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes } 330153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes if (mTextColor != null) { 331153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes itemView.setTextColor(mTextColor); 332153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes } 3331a542ba7235ec038f7ec1ac0ed65f35d29f5c952Yuichi Araki itemView.setBackgroundDrawable(mItemBackground != null ? 3341a542ba7235ec038f7ec1ac0ed65f35d29f5c952Yuichi Araki mItemBackground.getConstantState().newDrawable() : null); 33501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki itemView.initialize(item.getMenuItem(), 0); 33601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki break; 337ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes case VIEW_TYPE_SUBHEADER: 338ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes if (convertView == null) { 339ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes convertView = mLayoutInflater.inflate( 340ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes R.layout.design_navigation_item_subheader, parent, false); 341ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes } 342ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes TextView subHeader = (TextView) convertView; 34301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki subHeader.setText(item.getMenuItem().getTitle()); 34401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki break; 345ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes case VIEW_TYPE_SEPARATOR: 346ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes if (convertView == null) { 347ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes convertView = mLayoutInflater.inflate( 348ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes R.layout.design_navigation_item_separator, parent, false); 349ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes } 350ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes convertView.setPadding(0, item.getPaddingTop(), 0, 35160abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki item.getPaddingBottom()); 35201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki break; 35331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 354ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes return convertView; 355ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes } 35601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 357ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes @Override 358ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes public boolean areAllItemsEnabled() { 359ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes return false; 36001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 36101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 36201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki @Override 363ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes public boolean isEnabled(int position) { 364ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes return getItem(position).isEnabled(); 36501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 36601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 367ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes @Override 368ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes public void notifyDataSetChanged() { 3693a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes prepareMenuItems(); 370ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes super.notifyDataSetChanged(); 3713a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } 3723a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes 3733a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes /** 3743a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes * Flattens the visible menu items of {@link #mMenu} into {@link #mItems}, 3753a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes * while inserting separators between items when necessary. 3763a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes */ 3773a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes private void prepareMenuItems() { 37876bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki if (mUpdateSuspended) { 37976bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki return; 38076bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki } 38142db3143bed767c8e826e69f214672be358078ebYuichi Araki mUpdateSuspended = true; 3823a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes mItems.clear(); 3833a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes int currentGroupId = -1; 3843a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes int currentGroupStart = 0; 3853a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes boolean currentGroupHasIcon = false; 3863a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes for (int i = 0, totalSize = mMenu.getVisibleItems().size(); i < totalSize; i++) { 3873a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes MenuItemImpl item = mMenu.getVisibleItems().get(i); 388f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki if (item.isChecked()) { 389f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki setCheckedItem(item); 390f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki } 391f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki if (item.isCheckable()) { 392f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki item.setExclusiveCheckable(false); 393f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki } 3943a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes if (item.hasSubMenu()) { 3953a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes SubMenu subMenu = item.getSubMenu(); 3963a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes if (subMenu.hasVisibleItems()) { 3973a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes if (i != 0) { 398ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes mItems.add(NavigationMenuItem.separator(mPaddingSeparator, 0)); 3993a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } 400ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes mItems.add(NavigationMenuItem.of(item)); 4013a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes boolean subMenuHasIcon = false; 4023a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes int subMenuStart = mItems.size(); 4033a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes for (int j = 0, size = subMenu.size(); j < size; j++) { 404f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki MenuItemImpl subMenuItem = (MenuItemImpl) subMenu.getItem(j); 4053a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes if (subMenuItem.isVisible()) { 4063a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes if (!subMenuHasIcon && subMenuItem.getIcon() != null) { 4073a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes subMenuHasIcon = true; 4083a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } 409f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki if (subMenuItem.isCheckable()) { 410f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki subMenuItem.setExclusiveCheckable(false); 411f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki } 412f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki if (item.isChecked()) { 413f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki setCheckedItem(item); 414f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki } 415ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes mItems.add(NavigationMenuItem.of(subMenuItem)); 4163a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } 4173a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } 4183a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes if (subMenuHasIcon) { 4193a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes appendTransparentIconIfMissing(subMenuStart, mItems.size()); 4203a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } 4213a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } 4223a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } else { 4233a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes int groupId = item.getGroupId(); 4243a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes if (groupId != currentGroupId) { // first item in group 4253a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes currentGroupStart = mItems.size(); 4263a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes currentGroupHasIcon = item.getIcon() != null; 4273a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes if (i != 0) { 4283a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes currentGroupStart++; 429ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes mItems.add(NavigationMenuItem.separator( 43060abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki mPaddingSeparator, mPaddingSeparator)); 4313a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } 4323a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } else if (!currentGroupHasIcon && item.getIcon() != null) { 4333a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes currentGroupHasIcon = true; 4343a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes appendTransparentIconIfMissing(currentGroupStart, mItems.size()); 4353a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } 4363a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes if (currentGroupHasIcon && item.getIcon() == null) { 4373a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes item.setIcon(android.R.color.transparent); 4383a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } 439ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes mItems.add(NavigationMenuItem.of(item)); 4403a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes currentGroupId = groupId; 4413a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } 4423a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } 44342db3143bed767c8e826e69f214672be358078ebYuichi Araki mUpdateSuspended = false; 4443a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } 4453a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes 4463a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes private void appendTransparentIconIfMissing(int startIndex, int endIndex) { 4473a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes for (int i = startIndex; i < endIndex; i++) { 448ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes MenuItem item = mItems.get(i).getMenuItem(); 4493a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes if (item.getIcon() == null) { 4503a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes if (mTransparentIcon == null) { 4513a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes mTransparentIcon = new ColorDrawable(android.R.color.transparent); 4523a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } 4533a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes item.setIcon(mTransparentIcon); 4543a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } 4553a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } 4563a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } 45776bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki 458f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki public void setCheckedItem(MenuItemImpl checkedItem) { 459f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki if (mCheckedItem == checkedItem || !checkedItem.isCheckable()) { 460f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki return; 461f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki } 462f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki if (mCheckedItem != null) { 463f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki mCheckedItem.setChecked(false); 464f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki } 465f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki mCheckedItem = checkedItem; 466f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki checkedItem.setChecked(true); 467f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki } 468f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki 46976bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki public Bundle createInstanceState() { 47076bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki Bundle state = new Bundle(); 471024b36390fce843107b0916f0c3468e5a67a212aYuichi Araki if (mCheckedItem != null) { 472024b36390fce843107b0916f0c3468e5a67a212aYuichi Araki state.putInt(STATE_CHECKED_ITEM, mCheckedItem.getItemId()); 473024b36390fce843107b0916f0c3468e5a67a212aYuichi Araki } 47436d347c02fa8da71ccd69634484be8156fa0085bYuichi Araki // Store the states of the action views. 47536d347c02fa8da71ccd69634484be8156fa0085bYuichi Araki SparseArray<ParcelableSparseArray> actionViewStates = new SparseArray<>(); 47636d347c02fa8da71ccd69634484be8156fa0085bYuichi Araki for (NavigationMenuItem navigationMenuItem : mItems) { 477ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes MenuItemImpl item = navigationMenuItem.getMenuItem(); 478ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes View actionView = item != null ? item.getActionView() : null; 479ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes if (actionView != null) { 480ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes ParcelableSparseArray container = new ParcelableSparseArray(); 481ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes actionView.saveHierarchyState(container); 482ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes actionViewStates.put(item.getItemId(), container); 48336d347c02fa8da71ccd69634484be8156fa0085bYuichi Araki } 48436d347c02fa8da71ccd69634484be8156fa0085bYuichi Araki } 48536d347c02fa8da71ccd69634484be8156fa0085bYuichi Araki state.putSparseParcelableArray(STATE_ACTION_VIEWS, actionViewStates); 48676bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki return state; 48776bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki } 48876bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki 48976bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki public void restoreInstanceState(Bundle state) { 490f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki int checkedItem = state.getInt(STATE_CHECKED_ITEM, 0); 491f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki if (checkedItem != 0) { 49276bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki mUpdateSuspended = true; 49376bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki for (NavigationMenuItem item : mItems) { 494ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes MenuItemImpl menuItem = item.getMenuItem(); 495ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes if (menuItem != null && menuItem.getItemId() == checkedItem) { 496ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes setCheckedItem(menuItem); 497ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes break; 49876bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki } 49976bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki } 50076bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki mUpdateSuspended = false; 50176bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki prepareMenuItems(); 50276bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki } 50336d347c02fa8da71ccd69634484be8156fa0085bYuichi Araki // Restore the states of the action views. 50436d347c02fa8da71ccd69634484be8156fa0085bYuichi Araki SparseArray<ParcelableSparseArray> actionViewStates = state 50536d347c02fa8da71ccd69634484be8156fa0085bYuichi Araki .getSparseParcelableArray(STATE_ACTION_VIEWS); 50636d347c02fa8da71ccd69634484be8156fa0085bYuichi Araki for (NavigationMenuItem navigationMenuItem : mItems) { 507ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes MenuItemImpl item = navigationMenuItem.getMenuItem(); 508ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes View actionView = item != null ? item.getActionView() : null; 509ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes if (actionView != null) { 510ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes actionView.restoreHierarchyState(actionViewStates.get(item.getItemId())); 51136d347c02fa8da71ccd69634484be8156fa0085bYuichi Araki } 51236d347c02fa8da71ccd69634484be8156fa0085bYuichi Araki } 51376bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki } 51476bd4d2c1173100ab73c4f27dc42dd917c48915fYuichi Araki 515cc7a09fc0018e348027151daecf581b1d1b78f11Yuichi Araki public void setUpdateSuspended(boolean updateSuspended) { 516cc7a09fc0018e348027151daecf581b1d1b78f11Yuichi Araki mUpdateSuspended = updateSuspended; 517cc7a09fc0018e348027151daecf581b1d1b78f11Yuichi Araki } 518cc7a09fc0018e348027151daecf581b1d1b78f11Yuichi Araki 51901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 52001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 52101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki /** 522ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes * Wraps {@link MenuItemImpl}. This allows separators to be counted as items in list. 523e7b2c26d2ffadc94dc6ee043ab12e03201e1bf95Yuichi Araki */ 524ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes private static class NavigationMenuItem { 52560abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki 526ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes /** The item; null for separators */ 527e7b2c26d2ffadc94dc6ee043ab12e03201e1bf95Yuichi Araki private final MenuItemImpl mMenuItem; 52860abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki 529ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes /** Padding top; used only for separators */ 530e7b2c26d2ffadc94dc6ee043ab12e03201e1bf95Yuichi Araki private final int mPaddingTop; 531e7b2c26d2ffadc94dc6ee043ab12e03201e1bf95Yuichi Araki 532ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes /** Padding bottom; used only for separators */ 533e7b2c26d2ffadc94dc6ee043ab12e03201e1bf95Yuichi Araki private final int mPaddingBottom; 534e7b2c26d2ffadc94dc6ee043ab12e03201e1bf95Yuichi Araki 535ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes private NavigationMenuItem(MenuItemImpl item, int paddingTop, int paddingBottom) { 536ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes mMenuItem = item; 537e7b2c26d2ffadc94dc6ee043ab12e03201e1bf95Yuichi Araki mPaddingTop = paddingTop; 538e7b2c26d2ffadc94dc6ee043ab12e03201e1bf95Yuichi Araki mPaddingBottom = paddingBottom; 53960abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki } 54060abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki 541ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes public static NavigationMenuItem of(MenuItemImpl item) { 542ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes return new NavigationMenuItem(item, 0, 0); 543ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes } 544ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes 545ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes public static NavigationMenuItem separator(int paddingTop, int paddingBottom) { 546ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes return new NavigationMenuItem(null, paddingTop, paddingBottom); 547ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes } 548ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes 549ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes public boolean isSeparator() { 550ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes return mMenuItem == null; 551ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes } 552ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes 55360abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki public int getPaddingTop() { 55460abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki return mPaddingTop; 55560abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki } 55660abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki 55760abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki public int getPaddingBottom() { 55860abdeb39630c4c74a4c401e221f0c968caa26f5Yuichi Araki return mPaddingBottom; 55901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 56001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 561ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes public MenuItemImpl getMenuItem() { 562ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes return mMenuItem; 563ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes } 564ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes 565ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes public boolean isEnabled() { 566ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes // Separators and subheaders never respond to click 567ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes return mMenuItem != null && !mMenuItem.hasSubMenu() && mMenuItem.isEnabled(); 568ca2f07c9cc83b98d73a18da7177044ee147ffb94Chris Banes } 56901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 57031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 57131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 57231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki} 573