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.widget; 1831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 1931a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.content.Context; 20d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Arakiimport android.content.res.ColorStateList; 2131a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.content.res.TypedArray; 22a63940ca14cd3ad9620e94f709930bb968525c57Chris Banesimport android.graphics.drawable.Drawable; 2301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Arakiimport android.os.Bundle; 2401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Arakiimport android.os.Parcel; 2501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Arakiimport android.os.Parcelable; 26d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Arakiimport android.support.annotation.DrawableRes; 27f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Arakiimport android.support.annotation.IdRes; 2801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Arakiimport android.support.annotation.LayoutRes; 2901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Arakiimport android.support.annotation.NonNull; 30d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Arakiimport android.support.annotation.Nullable; 31153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banesimport android.support.annotation.StyleRes; 3231a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.support.design.R; 336c72ea0134a3309ff8197f0862aad8d7bc712b55Yuichi Arakiimport android.support.design.internal.NavigationMenu; 3431a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.support.design.internal.NavigationMenuPresenter; 3531a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.support.design.internal.ScrimInsetsFrameLayout; 36a63940ca14cd3ad9620e94f709930bb968525c57Chris Banesimport android.support.v4.content.ContextCompat; 3731a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.support.v4.view.ViewCompat; 383a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banesimport android.support.v7.internal.view.SupportMenuInflater; 3931a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.support.v7.internal.view.menu.MenuBuilder; 40f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Arakiimport android.support.v7.internal.view.menu.MenuItemImpl; 4131a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.util.AttributeSet; 42a63940ca14cd3ad9620e94f709930bb968525c57Chris Banesimport android.util.TypedValue; 4331a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.view.Menu; 443a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banesimport android.view.MenuInflater; 4531a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.view.MenuItem; 4631a49efe2adb59e31611f6871895a3243d835127Yuichi Arakiimport android.view.View; 4731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 4831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki/** 49a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki * Represents a standard navigation menu for application. The menu contents can be populated 50a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki * by a menu resource file. 51a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki * <p>NavigationView is typically placed inside a {@link android.support.v4.widget.DrawerLayout}. 5231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * </p> 5331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * <pre> 5431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" 5531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * xmlns:app="http://schemas.android.com/apk/res-auto" 5631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * android:id="@+id/drawer_layout" 5731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * android:layout_width="match_parent" 5831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * android:layout_height="match_parent" 5931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * android:fitsSystemWindows="true"> 6031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * 6131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * <!-- Your contents --> 6231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * 63a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki * <android.support.design.widget.NavigationView 64a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki * android:id="@+id/navigation" 6531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * android:layout_width="wrap_content" 6631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * android:layout_height="match_parent" 673a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes * android:layout_gravity="start" 683a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes * app:menu="@menu/my_navigation_items" /> 6931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * </android.support.v4.widget.DrawerLayout> 7031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * </pre> 7131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki */ 72a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Arakipublic class NavigationView extends ScrimInsetsFrameLayout { 7331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 74a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes private static final int[] CHECKED_STATE_SET = {android.R.attr.state_checked}; 75a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes private static final int[] DISABLED_STATE_SET = {-android.R.attr.state_enabled}; 76a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes 773a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes private static final int PRESENTER_NAVIGATION_VIEW_ID = 1; 7801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 796c72ea0134a3309ff8197f0862aad8d7bc712b55Yuichi Araki private final NavigationMenu mMenu; 809d9e5f050714c1f82c3c1adeab97c9a83a795d9eYuichi Araki private final NavigationMenuPresenter mPresenter = new NavigationMenuPresenter(); 8101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 823a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes private OnNavigationItemSelectedListener mListener; 8331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki private int mMaxWidth; 8431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 853a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes private MenuInflater mMenuInflater; 863a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes 87a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki public NavigationView(Context context) { 8831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki this(context, null); 8931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 9031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 91a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki public NavigationView(Context context, AttributeSet attrs) { 9231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki this(context, attrs, 0); 9331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 9431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 95a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki public NavigationView(Context context, AttributeSet attrs, int defStyleAttr) { 9631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki super(context, attrs, defStyleAttr); 9731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 983a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes // Create the menu 996c72ea0134a3309ff8197f0862aad8d7bc712b55Yuichi Araki mMenu = new NavigationMenu(context); 1003a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes 10131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki // Custom attributes 10231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki TypedArray a = context.obtainStyledAttributes(attrs, 103a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki R.styleable.NavigationView, defStyleAttr, 104a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki R.style.Widget_Design_NavigationView); 10531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 10631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki //noinspection deprecation 107a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki setBackgroundDrawable(a.getDrawable(R.styleable.NavigationView_android_background)); 1083a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes if (a.hasValue(R.styleable.NavigationView_elevation)) { 1093a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes ViewCompat.setElevation(this, a.getDimensionPixelSize( 1103a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes R.styleable.NavigationView_elevation, 0)); 1113a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } 11231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki ViewCompat.setFitsSystemWindows(this, 113a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki a.getBoolean(R.styleable.NavigationView_android_fitsSystemWindows, false)); 1143a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes 115a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki mMaxWidth = a.getDimensionPixelSize(R.styleable.NavigationView_android_maxWidth, 0); 1163a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes 117a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes final ColorStateList itemIconTint; 118a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes if (a.hasValue(R.styleable.NavigationView_itemIconTint)) { 119a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes itemIconTint = a.getColorStateList(R.styleable.NavigationView_itemIconTint); 120a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes } else { 121a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes itemIconTint = createDefaultColorStateList(android.R.attr.textColorSecondary); 122a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes } 1233a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes 124153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes boolean textAppearanceSet = false; 125153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes int textAppearance = 0; 126153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes if (a.hasValue(R.styleable.NavigationView_itemTextAppearance)) { 127153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes textAppearance = a.getResourceId(R.styleable.NavigationView_itemTextAppearance, 0); 128153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes textAppearanceSet = true; 129153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes } 130153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes 131153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes ColorStateList itemTextColor = null; 132a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes if (a.hasValue(R.styleable.NavigationView_itemTextColor)) { 133a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes itemTextColor = a.getColorStateList(R.styleable.NavigationView_itemTextColor); 134153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes } 135153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes 136153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes if (!textAppearanceSet && itemTextColor == null) { 137153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes // If there isn't a text appearance set, we'll use a default text color 138a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes itemTextColor = createDefaultColorStateList(android.R.attr.textColorPrimary); 139a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes } 140a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes 141a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes final Drawable itemBackground = a.getDrawable(R.styleable.NavigationView_itemBackground); 14231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 14301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki mMenu.setCallback(new MenuBuilder.Callback() { 14431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki @Override 14531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { 14631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki return mListener != null && mListener.onNavigationItemSelected(item); 14731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 14831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 14931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki @Override 1503a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes public void onMenuModeChange(MenuBuilder menu) {} 15101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki }); 1523a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes mPresenter.setId(PRESENTER_NAVIGATION_VIEW_ID); 15301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki mPresenter.initForMenu(context, mMenu); 154a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes mPresenter.setItemIconTintList(itemIconTint); 155153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes if (textAppearanceSet) { 156153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes mPresenter.setItemTextAppearance(textAppearance); 157153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes } 158a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes mPresenter.setItemTextColor(itemTextColor); 159a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes mPresenter.setItemBackground(itemBackground); 16001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki mMenu.addMenuPresenter(mPresenter); 16101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki addView((View) mPresenter.getMenuView(this)); 1623a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes 1639d9e5f050714c1f82c3c1adeab97c9a83a795d9eYuichi Araki if (a.hasValue(R.styleable.NavigationView_menu)) { 1649d9e5f050714c1f82c3c1adeab97c9a83a795d9eYuichi Araki inflateMenu(a.getResourceId(R.styleable.NavigationView_menu, 0)); 1659d9e5f050714c1f82c3c1adeab97c9a83a795d9eYuichi Araki } 1669d9e5f050714c1f82c3c1adeab97c9a83a795d9eYuichi Araki 1670cf8ecaeccbd07b5259927569eaf79e9a275d34fChris Banes if (a.hasValue(R.styleable.NavigationView_headerLayout)) { 1680cf8ecaeccbd07b5259927569eaf79e9a275d34fChris Banes inflateHeaderView(a.getResourceId(R.styleable.NavigationView_headerLayout, 0)); 1690cf8ecaeccbd07b5259927569eaf79e9a275d34fChris Banes } 1700cf8ecaeccbd07b5259927569eaf79e9a275d34fChris Banes 1713a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes a.recycle(); 17201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 17301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 17401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki @Override 17501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki protected Parcelable onSaveInstanceState() { 17601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki Parcelable superState = super.onSaveInstanceState(); 17701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki SavedState state = new SavedState(superState); 17801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki state.menuState = new Bundle(); 17901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki mMenu.savePresenterStates(state.menuState); 18001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki return state; 18101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 18201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 18301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki @Override 18401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki protected void onRestoreInstanceState(Parcelable savedState) { 18501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki SavedState state = (SavedState) savedState; 18601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki super.onRestoreInstanceState(state.getSuperState()); 18701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki mMenu.restorePresenterStates(state.menuState); 18831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 18931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 19031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki /** 19131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * Set a listener that will be notified when a menu item is clicked. 19231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * 19331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * @param listener The listener to notify 19431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki */ 19531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki public void setNavigationItemSelectedListener(OnNavigationItemSelectedListener listener) { 19631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki mListener = listener; 19731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 19831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 19931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki @Override 20031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki protected void onMeasure(int widthSpec, int heightSpec) { 20131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki switch (MeasureSpec.getMode(widthSpec)) { 20231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki case MeasureSpec.EXACTLY: 20331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki // Nothing to do 20431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki break; 20531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki case MeasureSpec.AT_MOST: 20631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki widthSpec = MeasureSpec.makeMeasureSpec( 20731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki Math.min(MeasureSpec.getSize(widthSpec), mMaxWidth), MeasureSpec.EXACTLY); 20831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki break; 20931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki case MeasureSpec.UNSPECIFIED: 21031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki widthSpec = MeasureSpec.makeMeasureSpec(mMaxWidth, MeasureSpec.EXACTLY); 21131a49efe2adb59e31611f6871895a3243d835127Yuichi Araki break; 21231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 21331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki // Let super sort out the height 21431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki super.onMeasure(widthSpec, heightSpec); 21531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 21631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 2173a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes 2183a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes /** 2193a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes * Inflate a menu resource into this navigation view. 2203a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes * 2213a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes * <p>Existing items in the menu will not be modified or removed.</p> 2223a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes * 2233a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes * @param resId ID of a menu resource to inflate 2243a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes */ 2253a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes public void inflateMenu(int resId) { 2269d9e5f050714c1f82c3c1adeab97c9a83a795d9eYuichi Araki mPresenter.setUpdateSuspended(true); 2273a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes getMenuInflater().inflate(resId, mMenu); 2289d9e5f050714c1f82c3c1adeab97c9a83a795d9eYuichi Araki mPresenter.setUpdateSuspended(false); 2299d9e5f050714c1f82c3c1adeab97c9a83a795d9eYuichi Araki mPresenter.updateMenuView(false); 2303a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } 2313a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes 23231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki /** 2333a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes * Returns the {@link Menu} instance associated with this navigation view. 23431a49efe2adb59e31611f6871895a3243d835127Yuichi Araki */ 23531a49efe2adb59e31611f6871895a3243d835127Yuichi Araki public Menu getMenu() { 23631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki return mMenu; 23731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 23831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 23931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki /** 24001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki * Inflates a View and add it as a header of the navigation menu. 24101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki * 24201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki * @param res The layout resource ID. 24301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki * @return a newly inflated View. 24401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki */ 24501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki public View inflateHeaderView(@LayoutRes int res) { 24601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki return mPresenter.inflateHeaderView(res); 24701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 24801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 24901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki /** 25001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki * Adds a View as a header of the navigation menu. 25101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki * 25201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki * @param view The view to be added as a header of the navigation menu. 25301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki */ 25401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki public void addHeaderView(@NonNull View view) { 25501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki mPresenter.addHeaderView(view); 25601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 25701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 25801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki /** 25901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki * Removes a previously-added header view. 26001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki * 26101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki * @param view The view to remove 26201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki */ 26301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki public void removeHeaderView(@NonNull View view) { 26401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki mPresenter.removeHeaderView(view); 26501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 26601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 26701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki /** 268a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * Returns the tint which is applied to our item's icons. 269a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * 270a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * @see #setItemIconTintList(ColorStateList) 271d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki * 272a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * @attr ref R.styleable#NavigationView_itemIconTint 273d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki */ 274d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki @Nullable 275a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes public ColorStateList getItemIconTintList() { 276d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki return mPresenter.getItemTintList(); 277d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki } 278d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki 279d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki /** 280a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * Set the tint which is applied to our item's icons. 281a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * 282a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * @param tint the tint to apply. 283a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * 284a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * @attr ref R.styleable#NavigationView_itemIconTint 285a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes */ 286a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes public void setItemIconTintList(@Nullable ColorStateList tint) { 287a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes mPresenter.setItemIconTintList(tint); 288a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes } 289a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes 290a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes /** 291a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * Returns the tint which is applied to our item's icons. 292a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * 293a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * @see #setItemTextColor(ColorStateList) 294a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * 295a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * @attr ref R.styleable#NavigationView_itemTextColor 296a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes */ 297a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes @Nullable 298a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes public ColorStateList getItemTextColor() { 299a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes return mPresenter.getItemTextColor(); 300a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes } 301a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes 302a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes /** 303a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * Set the text color which is text to our items. 304a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * 305a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * @see #getItemTextColor() 306d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki * 307a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * @attr ref R.styleable#NavigationView_itemTextColor 308d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki */ 309a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes public void setItemTextColor(@Nullable ColorStateList textColor) { 310a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes mPresenter.setItemTextColor(textColor); 311d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki } 312d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki 313d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki /** 314a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * Returns the background drawable for the menu items. 315d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki * 316d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki * @see #setItemBackgroundResource(int) 317a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * 318a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki * @attr ref R.styleable#NavigationView_itemBackground 319d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki */ 320a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes public Drawable getItemBackground() { 321a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes return mPresenter.getItemBackground(); 322a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes } 323a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes 324a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes /** 325a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * Set the background of the menu items to the given resource. 326a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * 327a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * @param resId The identifier of the resource. 328a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * 329a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * @attr ref R.styleable#NavigationView_itemBackground 330a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes */ 331a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes public void setItemBackgroundResource(@DrawableRes int resId) { 332a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes setItemBackground(ContextCompat.getDrawable(getContext(), resId)); 333d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki } 334d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki 335d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki /** 336d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki * Set the background of the menu items to a given resource. The resource should refer to 337d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki * a Drawable object or 0 to use the background background. 338d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki * 339a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki * @attr ref R.styleable#NavigationView_itemBackground 340d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki */ 341a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes public void setItemBackground(Drawable itemBackground) { 342a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes mPresenter.setItemBackground(itemBackground); 343d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki } 344d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki 345f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki /** 346f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki * Sets the currently checked item in this navigation menu. 347f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki * 348f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki * @param id The item ID of the currently checked item. 349f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki */ 350f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki public void setCheckedItem(@IdRes int id) { 351f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki MenuItem item = mMenu.findItem(id); 352f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki if (item != null) { 353f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki mPresenter.setCheckedItem((MenuItemImpl) item); 354f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki } 355f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki } 356f9b8005bf607feddd9b482f817bd68c46739e4f1Yuichi Araki 357153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes /** 358153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes * Set the text appearance of the menu items to a given resource. 359153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes * 360153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes * @attr ref R.styleable#NavigationView_itemTextAppearance 361153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes */ 362153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes public void setItemTextAppearance(@StyleRes int resId) { 363153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes mPresenter.setItemTextAppearance(resId); 364153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes } 365153fa9a03422419cd56b7d17def1ae907fc7b5cfChris Banes 3663a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes private MenuInflater getMenuInflater() { 3673a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes if (mMenuInflater == null) { 3683a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes mMenuInflater = new SupportMenuInflater(getContext()); 3693a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } 3703a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes return mMenuInflater; 3713a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes } 3723a2c9c408e240e761b043139c5d228d3ad93f6c2Chris Banes 373a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes private ColorStateList createDefaultColorStateList(int baseColorThemeAttr) { 374a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes TypedValue value = new TypedValue(); 375a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes if (!getContext().getTheme().resolveAttribute(baseColorThemeAttr, value, true)) { 376a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes return null; 377a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes } 378a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes ColorStateList baseColor = getResources().getColorStateList(value.resourceId); 379a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes if (!getContext().getTheme().resolveAttribute(R.attr.colorPrimary, value, true)) { 380a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes return null; 381a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes } 382a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes int colorPrimary = value.data; 383a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes int defaultColor = baseColor.getDefaultColor(); 384a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes return new ColorStateList(new int[][]{ 385a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes DISABLED_STATE_SET, 386a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes CHECKED_STATE_SET, 387a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes EMPTY_STATE_SET 388a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes }, new int[]{ 389a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes baseColor.getColorForState(DISABLED_STATE_SET, defaultColor), 390a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes colorPrimary, 391a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes defaultColor 392a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes }); 393a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes } 394a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes 395d3ee2c7d22c0cb204ea9077fa9e64511266d6799Yuichi Araki /** 396a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki * Listener for handling events on navigation items. 39731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki */ 39831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki public interface OnNavigationItemSelectedListener { 39931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 40031a49efe2adb59e31611f6871895a3243d835127Yuichi Araki /** 401a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki * Called when an item in the navigation menu is selected. 40231a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * 40331a49efe2adb59e31611f6871895a3243d835127Yuichi Araki * @param item The selected item 404a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * 405a63940ca14cd3ad9620e94f709930bb968525c57Chris Banes * @return true to display the item as the selected item 40631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki */ 40731a49efe2adb59e31611f6871895a3243d835127Yuichi Araki public boolean onNavigationItemSelected(MenuItem item); 40831a49efe2adb59e31611f6871895a3243d835127Yuichi Araki } 40931a49efe2adb59e31611f6871895a3243d835127Yuichi Araki 41001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki /** 411a5081dfb26b3664d97d5fe09b9b6a9c9667e0e9fYuichi Araki * User interface state that is stored by NavigationView for implementing 41201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki * onSaveInstanceState(). 41301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki */ 41401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki public static class SavedState extends BaseSavedState { 41501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki public Bundle menuState; 41601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 41701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki public SavedState(Parcel in) { 41801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki super(in); 41901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki menuState = in.readBundle(); 42001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 42101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 42201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki public SavedState(Parcelable superState) { 42301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki super(superState); 42401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 42501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 42601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki @Override 42701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki public void writeToParcel(@NonNull Parcel dest, int flags) { 42801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki super.writeToParcel(dest, flags); 42901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki dest.writeBundle(menuState); 43001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 43101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 43201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki public static final Parcelable.Creator<SavedState> CREATOR 43301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki = new Parcelable.Creator<SavedState>() { 43401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki @Override 43501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki public SavedState createFromParcel(Parcel parcel) { 43601090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki return new SavedState(parcel); 43701090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 43801090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 43901090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki @Override 44001090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki public SavedState[] newArray(int size) { 44101090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki return new SavedState[size]; 44201090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 44301090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki }; 44401090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki } 44501090f9556e7518c9ee206de6efe42de9003f6f5Yuichi Araki 44631a49efe2adb59e31611f6871895a3243d835127Yuichi Araki} 447