1e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas/* 2e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas * Copyright (C) 2016 The Android Open Source Project 3e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas * 4e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas * Licensed under the Apache License, Version 2.0 (the "License"); 5e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas * you may not use this file except in compliance with the License. 6e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas * You may obtain a copy of the License at 7e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas * 8e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas * http://www.apache.org/licenses/LICENSE-2.0 9e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas * 10e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas * Unless required by applicable law or agreed to in writing, software 11e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas * distributed under the License is distributed on an "AS IS" BASIS, 12e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas * See the License for the specific language governing permissions and 14e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas * limitations under the License. 15e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas */ 16e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikaspackage android.support.design.widget; 17e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas 18910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikasimport static android.support.design.testutils.BottomNavigationViewActions.setIconForMenuItem; 19910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikasimport static android.support.design.testutils.BottomNavigationViewActions.setItemIconTintList; 20e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikasimport static android.support.test.espresso.Espresso.onView; 21e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikasimport static android.support.test.espresso.action.ViewActions.click; 22910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikasimport static android.support.test.espresso.assertion.ViewAssertions.matches; 23910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikasimport static android.support.test.espresso.matcher.ViewMatchers.isDescendantOfA; 2403cbbe6c4bb2f52c0f67e961e12d869d93163b59Aurimas Liutikasimport static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; 25910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikasimport static android.support.test.espresso.matcher.ViewMatchers.withId; 26910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikasimport static android.support.test.espresso.matcher.ViewMatchers.withText; 27910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas 28910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikasimport static org.hamcrest.core.AllOf.allOf; 29910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikasimport static org.junit.Assert.assertEquals; 30578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikasimport static org.junit.Assert.assertFalse; 31910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikasimport static org.junit.Assert.assertNotNull; 32578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikasimport static org.junit.Assert.assertTrue; 33578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikasimport static org.mockito.Matchers.any; 34910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikasimport static org.mockito.Mockito.mock; 356b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Korenimport static org.mockito.Mockito.never; 36910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikasimport static org.mockito.Mockito.times; 37910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikasimport static org.mockito.Mockito.verify; 38910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikasimport static org.mockito.Mockito.verifyNoMoreInteractions; 39578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikasimport static org.mockito.Mockito.when; 40e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas 41ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheevimport android.app.Activity; 42e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikasimport android.content.res.Resources; 43ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheevimport android.os.Build; 44b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Korenimport android.os.Parcelable; 45910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikasimport android.support.annotation.ColorInt; 46e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikasimport android.support.design.test.R; 47910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikasimport android.support.design.testutils.TestDrawable; 48910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikasimport android.support.design.testutils.TestUtilsMatchers; 4980c46a0294ce910b675c27326cd677a724ddd7bfAurimas Liutikasimport android.support.test.annotation.UiThreadTest; 5035232c6eaeb9b99f390cb8ef0ac83bf45fa0b3faAurimas Liutikasimport android.support.test.filters.LargeTest; 51ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheevimport android.support.test.filters.SdkSuppress; 52754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport android.support.test.filters.SmallTest; 53910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikasimport android.support.v4.content.res.ResourcesCompat; 54e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikasimport android.view.Menu; 55e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikasimport android.view.MenuItem; 56ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheevimport android.view.MotionEvent; 57ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheevimport android.view.PointerIcon; 58ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheevimport android.view.View; 59c40f445372d08cc251ee70f3dfe65e4e87ee4276Jonathan Korenimport android.view.ViewGroup; 60e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas 61e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikasimport org.junit.Before; 62e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikasimport org.junit.Test; 63e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas 64e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikasimport java.util.HashMap; 65e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikasimport java.util.Map; 66e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas 67e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikaspublic class BottomNavigationViewTest 68e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas extends BaseInstrumentationTestCase<BottomNavigationViewActivity> { 69e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas private static final int[] MENU_CONTENT_ITEM_IDS = { R.id.destination_home, 70e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas R.id.destination_profile, R.id.destination_people }; 71e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas private Map<Integer, String> mMenuStringContent; 72e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas 73e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas private BottomNavigationView mBottomNavigation; 74e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas 75e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas public BottomNavigationViewTest() { 76e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas super(BottomNavigationViewActivity.class); 77e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas } 78e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas 79e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas @Before 80e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas public void setUp() throws Exception { 81e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas final BottomNavigationViewActivity activity = mActivityTestRule.getActivity(); 82e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas mBottomNavigation = (BottomNavigationView) activity.findViewById(R.id.bottom_navigation); 83e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas 84e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas final Resources res = activity.getResources(); 85e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas mMenuStringContent = new HashMap<>(MENU_CONTENT_ITEM_IDS.length); 86e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas mMenuStringContent.put(R.id.destination_home, res.getString(R.string.navigate_home)); 87e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas mMenuStringContent.put(R.id.destination_profile, res.getString(R.string.navigate_profile)); 88e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas mMenuStringContent.put(R.id.destination_people, res.getString(R.string.navigate_people)); 89e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas } 90e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas 9180c46a0294ce910b675c27326cd677a724ddd7bfAurimas Liutikas @UiThreadTest 9280c46a0294ce910b675c27326cd677a724ddd7bfAurimas Liutikas @Test 9380c46a0294ce910b675c27326cd677a724ddd7bfAurimas Liutikas @SmallTest 9480c46a0294ce910b675c27326cd677a724ddd7bfAurimas Liutikas public void testAddItemsWithoutMenuInflation() { 9580c46a0294ce910b675c27326cd677a724ddd7bfAurimas Liutikas BottomNavigationView navigation = new BottomNavigationView(mActivityTestRule.getActivity()); 9680c46a0294ce910b675c27326cd677a724ddd7bfAurimas Liutikas mActivityTestRule.getActivity().setContentView(navigation); 9780c46a0294ce910b675c27326cd677a724ddd7bfAurimas Liutikas navigation.getMenu().add("Item1"); 9880c46a0294ce910b675c27326cd677a724ddd7bfAurimas Liutikas navigation.getMenu().add("Item2"); 9980c46a0294ce910b675c27326cd677a724ddd7bfAurimas Liutikas assertEquals(2, navigation.getMenu().size()); 10080c46a0294ce910b675c27326cd677a724ddd7bfAurimas Liutikas navigation.getMenu().removeItem(0); 10180c46a0294ce910b675c27326cd677a724ddd7bfAurimas Liutikas navigation.getMenu().removeItem(0); 10280c46a0294ce910b675c27326cd677a724ddd7bfAurimas Liutikas assertEquals(0, navigation.getMenu().size()); 10380c46a0294ce910b675c27326cd677a724ddd7bfAurimas Liutikas } 10480c46a0294ce910b675c27326cd677a724ddd7bfAurimas Liutikas 105e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas @Test 106e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas @SmallTest 107e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas public void testBasics() { 108e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas // Check the contents of the Menu object 109e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas final Menu menu = mBottomNavigation.getMenu(); 110e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas assertNotNull("Menu should not be null", menu); 111e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas assertEquals("Should have matching number of items", MENU_CONTENT_ITEM_IDS.length, 112e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas menu.size()); 113e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas for (int i = 0; i < MENU_CONTENT_ITEM_IDS.length; i++) { 114e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas final MenuItem currItem = menu.getItem(i); 115e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas assertEquals("ID for Item #" + i, MENU_CONTENT_ITEM_IDS[i], currItem.getItemId()); 116e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas } 117e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas 118e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas } 119e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas 120e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas @Test 12135232c6eaeb9b99f390cb8ef0ac83bf45fa0b3faAurimas Liutikas @LargeTest 122e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas public void testNavigationSelectionListener() { 123e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas BottomNavigationView.OnNavigationItemSelectedListener mockedListener = 124e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas mock(BottomNavigationView.OnNavigationItemSelectedListener.class); 125e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas mBottomNavigation.setOnNavigationItemSelectedListener(mockedListener); 126e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas 127578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikas // Make the listener return true to allow selecting the item. 128578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikas when(mockedListener.onNavigationItemSelected(any(MenuItem.class))).thenReturn(true); 129e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas onView(allOf(withText(mMenuStringContent.get(R.id.destination_profile)), 13003cbbe6c4bb2f52c0f67e961e12d869d93163b59Aurimas Liutikas isDescendantOfA(withId(R.id.bottom_navigation)), isDisplayed())).perform(click()); 131578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikas // Verify our listener has been notified of the click 132e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas verify(mockedListener, times(1)).onNavigationItemSelected( 133e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas mBottomNavigation.getMenu().findItem(R.id.destination_profile)); 134578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikas // Verify the item is now selected 135578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikas assertTrue(mBottomNavigation.getMenu().findItem(R.id.destination_profile).isChecked()); 136578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikas 1376b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Select the same item again 1386b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren onView(allOf(withText(mMenuStringContent.get(R.id.destination_profile)), 1396b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren isDescendantOfA(withId(R.id.bottom_navigation)), isDisplayed())).perform(click()); 1406b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Verify our listener has been notified of the click 1416b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren verify(mockedListener, times(2)).onNavigationItemSelected( 1426b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren mBottomNavigation.getMenu().findItem(R.id.destination_profile)); 1436b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Verify the item is still selected 1446b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren assertTrue(mBottomNavigation.getMenu().findItem(R.id.destination_profile).isChecked()); 1456b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren 146578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikas // Make the listener return false to disallow selecting the item. 147578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikas when(mockedListener.onNavigationItemSelected(any(MenuItem.class))).thenReturn(false); 148578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikas onView(allOf(withText(mMenuStringContent.get(R.id.destination_people)), 149578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikas isDescendantOfA(withId(R.id.bottom_navigation)), isDisplayed())).perform(click()); 150578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikas // Verify our listener has been notified of the click 151578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikas verify(mockedListener, times(1)).onNavigationItemSelected( 152578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikas mBottomNavigation.getMenu().findItem(R.id.destination_people)); 153578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikas // Verify the previous item is still selected 154578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikas assertFalse(mBottomNavigation.getMenu().findItem(R.id.destination_people).isChecked()); 155578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikas assertTrue(mBottomNavigation.getMenu().findItem(R.id.destination_profile).isChecked()); 156e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas 157e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas // Set null listener to test that the next click is not going to notify the 158578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikas // previously set listener and will allow selecting items. 159e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas mBottomNavigation.setOnNavigationItemSelectedListener(null); 160e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas 161e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas // Click one of our items 162578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikas onView(allOf(withText(mMenuStringContent.get(R.id.destination_home)), 16303cbbe6c4bb2f52c0f67e961e12d869d93163b59Aurimas Liutikas isDescendantOfA(withId(R.id.bottom_navigation)), isDisplayed())).perform(click()); 164e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren // Verify that our previous listener has not been notified of the click 165e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas verifyNoMoreInteractions(mockedListener); 166578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikas // Verify the correct item is now selected. 167578015fc3e5ddc0fdb95db7ad0d00822c54be6dfAurimas Liutikas assertTrue(mBottomNavigation.getMenu().findItem(R.id.destination_home).isChecked()); 168e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas } 169910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas 170e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren @UiThreadTest 171e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren @Test 172e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren @SmallTest 173e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren public void testSetSelectedItemId() { 174e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren BottomNavigationView.OnNavigationItemSelectedListener mockedListener = 175e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren mock(BottomNavigationView.OnNavigationItemSelectedListener.class); 176e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren mBottomNavigation.setOnNavigationItemSelectedListener(mockedListener); 177e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren 178e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren // Make the listener return true to allow selecting the item. 179e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren when(mockedListener.onNavigationItemSelected(any(MenuItem.class))).thenReturn(true); 180e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren // Programmatically select an item 181e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren mBottomNavigation.setSelectedItemId(R.id.destination_profile); 182e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren // Verify our listener has been notified of the click 183e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren verify(mockedListener, times(1)).onNavigationItemSelected( 184e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren mBottomNavigation.getMenu().findItem(R.id.destination_profile)); 185e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren // Verify the item is now selected 186e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren assertTrue(mBottomNavigation.getMenu().findItem(R.id.destination_profile).isChecked()); 187e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren 1886b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Select the same item 1896b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren mBottomNavigation.setSelectedItemId(R.id.destination_profile); 1906b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Verify our listener has been notified of the click 1916b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren verify(mockedListener, times(2)).onNavigationItemSelected( 1926b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren mBottomNavigation.getMenu().findItem(R.id.destination_profile)); 1936b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Verify the item is still selected 1946b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren assertTrue(mBottomNavigation.getMenu().findItem(R.id.destination_profile).isChecked()); 1956b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren 196e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren // Make the listener return false to disallow selecting the item. 197e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren when(mockedListener.onNavigationItemSelected(any(MenuItem.class))).thenReturn(false); 198e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren // Programmatically select an item 199e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren mBottomNavigation.setSelectedItemId(R.id.destination_people); 200e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren // Verify our listener has been notified of the click 201e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren verify(mockedListener, times(1)).onNavigationItemSelected( 202e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren mBottomNavigation.getMenu().findItem(R.id.destination_people)); 203e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren // Verify the previous item is still selected 204e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren assertFalse(mBottomNavigation.getMenu().findItem(R.id.destination_people).isChecked()); 205e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren assertTrue(mBottomNavigation.getMenu().findItem(R.id.destination_profile).isChecked()); 206e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren 207e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren // Set null listener to test that the next click is not going to notify the 208e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren // previously set listener and will allow selecting items. 209e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren mBottomNavigation.setOnNavigationItemSelectedListener(null); 210e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren 211e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren // Select one of our items 212e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren mBottomNavigation.setSelectedItemId(R.id.destination_home); 213e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren // Verify that our previous listener has not been notified of the click 214e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren verifyNoMoreInteractions(mockedListener); 215e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren // Verify the correct item is now selected. 216e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren assertTrue(mBottomNavigation.getMenu().findItem(R.id.destination_home).isChecked()); 217e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren } 218e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren 2196b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren @Test 2206b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren @SmallTest 2216b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren public void testNavigationReselectionListener() { 2226b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Add an OnNavigationItemReselectedListener 2236b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren BottomNavigationView.OnNavigationItemReselectedListener reselectedListener = 2246b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren mock(BottomNavigationView.OnNavigationItemReselectedListener.class); 2256b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren mBottomNavigation.setOnNavigationItemReselectedListener(reselectedListener); 2266b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren 2276b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Select an item 2286b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren onView(allOf(withText(mMenuStringContent.get(R.id.destination_profile)), 2296b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren isDescendantOfA(withId(R.id.bottom_navigation)), isDisplayed())).perform(click()); 2306b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Verify the item is now selected 2316b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren assertTrue(mBottomNavigation.getMenu().findItem(R.id.destination_profile).isChecked()); 2326b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Verify the listener was not called 2336b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren verify(reselectedListener, never()).onNavigationItemReselected(any(MenuItem.class)); 2346b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren 2356b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Select the same item again 2366b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren onView(allOf(withText(mMenuStringContent.get(R.id.destination_profile)), 2376b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren isDescendantOfA(withId(R.id.bottom_navigation)), isDisplayed())).perform(click()); 2386b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Verify the item is still selected 2396b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren assertTrue(mBottomNavigation.getMenu().findItem(R.id.destination_profile).isChecked()); 2406b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Verify the listener was called 2416b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren verify(reselectedListener, times(1)).onNavigationItemReselected( 2426b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren mBottomNavigation.getMenu().findItem(R.id.destination_profile)); 2436b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren 2446b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Add an OnNavigationItemSelectedListener 2456b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren BottomNavigationView.OnNavigationItemSelectedListener selectedListener = 2466b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren mock(BottomNavigationView.OnNavigationItemSelectedListener.class); 2476b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren mBottomNavigation.setOnNavigationItemSelectedListener(selectedListener); 2486b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Make the listener return true to allow selecting the item. 2496b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren when(selectedListener.onNavigationItemSelected(any(MenuItem.class))).thenReturn(true); 2506b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren 2516b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Select another item 2526b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren onView(allOf(withText(mMenuStringContent.get(R.id.destination_people)), 2536b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren isDescendantOfA(withId(R.id.bottom_navigation)), isDisplayed())).perform(click()); 2546b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Verify the item is now selected 2556b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren assertTrue(mBottomNavigation.getMenu().findItem(R.id.destination_people).isChecked()); 2566b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Verify the correct listeners were called 2576b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren verify(selectedListener, times(1)).onNavigationItemSelected( 2586b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren mBottomNavigation.getMenu().findItem(R.id.destination_people)); 2596b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren verify(reselectedListener, never()).onNavigationItemReselected( 2606b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren mBottomNavigation.getMenu().findItem(R.id.destination_people)); 2616b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren 2626b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Select the same item again 2636b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren onView(allOf(withText(mMenuStringContent.get(R.id.destination_people)), 2646b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren isDescendantOfA(withId(R.id.bottom_navigation)), isDisplayed())).perform(click()); 2656b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Verify the item is still selected 2666b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren assertTrue(mBottomNavigation.getMenu().findItem(R.id.destination_people).isChecked()); 2676b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Verify the correct listeners were called 2686b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren verifyNoMoreInteractions(selectedListener); 2696b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren verify(reselectedListener, times(1)).onNavigationItemReselected( 2706b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren mBottomNavigation.getMenu().findItem(R.id.destination_people)); 2716b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren 2726b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Remove the OnNavigationItemReselectedListener 2736b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren mBottomNavigation.setOnNavigationItemReselectedListener(null); 2746b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren 2756b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Select the same item again 2766b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren onView(allOf(withText(mMenuStringContent.get(R.id.destination_people)), 2776b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren isDescendantOfA(withId(R.id.bottom_navigation)), isDisplayed())).perform(click()); 2786b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Verify the item is still selected 2796b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren assertTrue(mBottomNavigation.getMenu().findItem(R.id.destination_people).isChecked()); 2806b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren // Verify the reselectedListener was not called 2816b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren verifyNoMoreInteractions(reselectedListener); 2826b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren } 2836b3a399a8ed6afa4c9da88690a61efca61b61d21Jonathan Koren 284e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren @UiThreadTest 285e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren @Test 286e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren @SmallTest 287e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren public void testSelectedItemIdWithEmptyMenu() { 288e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren // First item initially selected 289e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren assertEquals(R.id.destination_home, mBottomNavigation.getSelectedItemId()); 290e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren 291e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren // Remove all the items 292e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren for (int id : mMenuStringContent.keySet()) { 293e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren mBottomNavigation.getMenu().removeItem(id); 294e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren } 295e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren // Verify selected ID is zero 296e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren assertEquals(0, mBottomNavigation.getSelectedItemId()); 297e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren 298e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren // Add an item 299e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren mBottomNavigation.getMenu().add(0, R.id.destination_home, 0, R.string.navigate_home); 300e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren // Verify item is selected 301e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren assertEquals(R.id.destination_home, mBottomNavigation.getSelectedItemId()); 302e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren 303e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren // Try selecting an invalid ID 304e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren mBottomNavigation.setSelectedItemId(R.id.destination_people); 305e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren // Verify the view has not changed 306e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren assertEquals(R.id.destination_home, mBottomNavigation.getSelectedItemId()); 307e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren } 308e4c7e61dbe94a77c5389eb20952d6b7ed6536cafJonathan Koren 309910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas @Test 310910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas @SmallTest 311910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas public void testIconTinting() { 312910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas final Resources res = mActivityTestRule.getActivity().getResources(); 313910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas @ColorInt final int redFill = ResourcesCompat.getColor(res, R.color.test_red, null); 314910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas @ColorInt final int greenFill = ResourcesCompat.getColor(res, R.color.test_green, null); 315910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas @ColorInt final int blueFill = ResourcesCompat.getColor(res, R.color.test_blue, null); 316910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas final int iconSize = res.getDimensionPixelSize(R.dimen.drawable_small_size); 317910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas onView(withId(R.id.bottom_navigation)).perform(setIconForMenuItem(R.id.destination_home, 318910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas new TestDrawable(redFill, iconSize, iconSize))); 319910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas onView(withId(R.id.bottom_navigation)).perform(setIconForMenuItem(R.id.destination_profile, 320910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas new TestDrawable(greenFill, iconSize, iconSize))); 321910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas onView(withId(R.id.bottom_navigation)).perform(setIconForMenuItem(R.id.destination_people, 322910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas new TestDrawable(blueFill, iconSize, iconSize))); 323910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas 324910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas @ColorInt final int defaultTintColor = ResourcesCompat.getColor(res, 325910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas R.color.emerald_translucent, null); 326910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas 327910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas // We're allowing a margin of error in checking the color of the items' icons. 328910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas // This is due to the translucent color being used in the icon tinting 329910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas // and off-by-one discrepancies of SRC_IN when it's compositing 330910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas // translucent color. Note that all the checks below are written for the current 331910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas // logic on BottomNavigationView that uses the default SRC_IN tint mode - effectively 332910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas // replacing all non-transparent pixels in the destination (original icon) with 333910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas // our translucent tint color. 334910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas final int allowedComponentVariance = 1; 335910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas 336910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas // Note that here we're tying ourselves to the implementation details of the internal 337910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas // structure of the BottomNavigationView. Specifically, we're checking the drawable the 338910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas // ImageView with id R.id.icon. If the internal implementation of BottomNavigationView 339910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas // changes, the second Matcher in the lookups below will need to be tweaked. 340910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas onView(allOf(withId(R.id.icon), isDescendantOfA(withId(R.id.destination_home)))).check( 341910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas matches(TestUtilsMatchers.drawable(defaultTintColor, allowedComponentVariance))); 342910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas onView(allOf(withId(R.id.icon), isDescendantOfA(withId(R.id.destination_profile)))).check( 343910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas matches(TestUtilsMatchers.drawable(defaultTintColor, allowedComponentVariance))); 344910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas onView(allOf(withId(R.id.icon), isDescendantOfA(withId(R.id.destination_people)))).check( 345910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas matches(TestUtilsMatchers.drawable(defaultTintColor, allowedComponentVariance))); 346910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas 347910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas @ColorInt final int newTintColor = ResourcesCompat.getColor(res, 348910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas R.color.red_translucent, null); 349910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas onView(withId(R.id.bottom_navigation)).perform(setItemIconTintList( 350910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas ResourcesCompat.getColorStateList(res, R.color.color_state_list_red_translucent, 351910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas null))); 352910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas // Check that all menu items with icons now have icons tinted with the newly set color 353910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas onView(allOf(withId(R.id.icon), isDescendantOfA(withId(R.id.destination_home)))).check( 354910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas matches(TestUtilsMatchers.drawable(newTintColor, allowedComponentVariance))); 355910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas onView(allOf(withId(R.id.icon), isDescendantOfA(withId(R.id.destination_profile)))).check( 356910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas matches(TestUtilsMatchers.drawable(newTintColor, allowedComponentVariance))); 357910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas onView(allOf(withId(R.id.icon), isDescendantOfA(withId(R.id.destination_people)))).check( 358910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas matches(TestUtilsMatchers.drawable(newTintColor, allowedComponentVariance))); 359910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas 360910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas // And now remove all icon tinting 361910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas onView(withId(R.id.bottom_navigation)).perform(setItemIconTintList(null)); 362910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas // And verify that all menu items with icons now have the original colors for their icons. 363910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas // Note that since there is no tinting at this point, we don't allow any color variance 364910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas // in these checks. 365910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas onView(allOf(withId(R.id.icon), isDescendantOfA(withId(R.id.destination_home)))).check( 366910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas matches(TestUtilsMatchers.drawable(redFill, allowedComponentVariance))); 367910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas onView(allOf(withId(R.id.icon), isDescendantOfA(withId(R.id.destination_profile)))).check( 368910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas matches(TestUtilsMatchers.drawable(greenFill, allowedComponentVariance))); 369910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas onView(allOf(withId(R.id.icon), isDescendantOfA(withId(R.id.destination_people)))).check( 370910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas matches(TestUtilsMatchers.drawable(blueFill, allowedComponentVariance))); 371910de28f0a195668fad38ad2367c1f7237a7af98Aurimas Liutikas } 37269557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas 37369557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas @UiThreadTest 37469557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas @Test 37569557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas @SmallTest 37669557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas public void testItemChecking() throws Throwable { 37769557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas final Menu menu = mBottomNavigation.getMenu(); 37869557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas assertTrue(menu.getItem(0).isChecked()); 37969557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas checkAndVerifyExclusiveItem(menu, R.id.destination_home); 38069557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas checkAndVerifyExclusiveItem(menu, R.id.destination_profile); 38169557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas checkAndVerifyExclusiveItem(menu, R.id.destination_people); 38269557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas } 38369557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas 384ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheev @UiThreadTest 385ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheev @Test 386ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheev @SmallTest 387ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheev @SdkSuppress(minSdkVersion = Build.VERSION_CODES.N) 388ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheev public void testPointerIcon() throws Throwable { 389ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheev final Activity activity = mActivityTestRule.getActivity(); 390ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheev final PointerIcon expectedIcon = PointerIcon.getSystemIcon(activity, PointerIcon.TYPE_HAND); 391ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheev final MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_HOVER_MOVE, 0, 0, 0); 392ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheev final Menu menu = mBottomNavigation.getMenu(); 393ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheev for (int i = 0; i < menu.size(); i++) { 394ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheev final MenuItem item = menu.getItem(i); 395ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheev assertTrue(item.isEnabled()); 396ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheev final View itemView = activity.findViewById(item.getItemId()); 397ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheev assertEquals(expectedIcon, itemView.onResolvePointerIcon(event, 0)); 398ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheev item.setEnabled(false); 399ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheev assertEquals(null, itemView.onResolvePointerIcon(event, 0)); 400ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheev item.setEnabled(true); 401ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheev assertEquals(expectedIcon, itemView.onResolvePointerIcon(event, 0)); 402ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheev } 403ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheev } 404ee6c89547f0f0321b66c7c21e1990e7870a45b3cVladislav Kaznacheev 4056249e1022b21b1b5a0ed40191561fe7ea5d1e1caAurimas Liutikas @UiThreadTest 4066249e1022b21b1b5a0ed40191561fe7ea5d1e1caAurimas Liutikas @Test 4076249e1022b21b1b5a0ed40191561fe7ea5d1e1caAurimas Liutikas @SmallTest 4082befdb72bff253ec493612aca2b527da765ae0d1Aurimas Liutikas public void testClearingMenu() throws Throwable { 4092befdb72bff253ec493612aca2b527da765ae0d1Aurimas Liutikas mBottomNavigation.getMenu().clear(); 4102befdb72bff253ec493612aca2b527da765ae0d1Aurimas Liutikas assertEquals(0, mBottomNavigation.getMenu().size()); 4112befdb72bff253ec493612aca2b527da765ae0d1Aurimas Liutikas mBottomNavigation.inflateMenu(R.menu.bottom_navigation_view_content); 4122befdb72bff253ec493612aca2b527da765ae0d1Aurimas Liutikas assertEquals(3, mBottomNavigation.getMenu().size()); 4132befdb72bff253ec493612aca2b527da765ae0d1Aurimas Liutikas } 4142befdb72bff253ec493612aca2b527da765ae0d1Aurimas Liutikas 415b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren @Test 416b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren @SmallTest 417b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren public void testSavedState() throws Throwable { 418b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren // Select an item other than the first 419b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren onView(allOf(withText(mMenuStringContent.get(R.id.destination_profile)), 420b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren isDescendantOfA(withId(R.id.bottom_navigation)), isDisplayed())).perform(click()); 421b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren assertTrue(mBottomNavigation.getMenu().findItem(R.id.destination_profile).isChecked()); 422b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren // Save the state 423b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren final Parcelable state = mBottomNavigation.onSaveInstanceState(); 424b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren 425b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren // Restore the state into a fresh BottomNavigationView 426b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren mActivityTestRule.runOnUiThread(new Runnable() { 427b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren @Override 428b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren public void run() { 429b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren BottomNavigationView testView = 430b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren new BottomNavigationView(mActivityTestRule.getActivity()); 431b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren testView.inflateMenu(R.menu.bottom_navigation_view_content); 432b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren testView.onRestoreInstanceState(state); 433b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren assertTrue(testView.getMenu().findItem(R.id.destination_profile).isChecked()); 434b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren } 435b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren }); 436b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren } 437b01c03a178cb74302b83e20820fb98a817b47e3eJonathan Koren 438c40f445372d08cc251ee70f3dfe65e4e87ee4276Jonathan Koren @UiThreadTest 439c40f445372d08cc251ee70f3dfe65e4e87ee4276Jonathan Koren @Test 440c40f445372d08cc251ee70f3dfe65e4e87ee4276Jonathan Koren @SmallTest 441c40f445372d08cc251ee70f3dfe65e4e87ee4276Jonathan Koren public void testContentDescription() { 442c40f445372d08cc251ee70f3dfe65e4e87ee4276Jonathan Koren ViewGroup menuView = (ViewGroup) mBottomNavigation.getChildAt(0); 443c40f445372d08cc251ee70f3dfe65e4e87ee4276Jonathan Koren final int count = menuView.getChildCount(); 444c40f445372d08cc251ee70f3dfe65e4e87ee4276Jonathan Koren for (int i = 0; i < count; i++) { 445c40f445372d08cc251ee70f3dfe65e4e87ee4276Jonathan Koren View child = menuView.getChildAt(i); 446c40f445372d08cc251ee70f3dfe65e4e87ee4276Jonathan Koren // We're using the same strings for content description 447c40f445372d08cc251ee70f3dfe65e4e87ee4276Jonathan Koren assertEquals(mMenuStringContent.get(child.getId()), 448c40f445372d08cc251ee70f3dfe65e4e87ee4276Jonathan Koren child.getContentDescription().toString()); 449c40f445372d08cc251ee70f3dfe65e4e87ee4276Jonathan Koren } 450c40f445372d08cc251ee70f3dfe65e4e87ee4276Jonathan Koren 451c40f445372d08cc251ee70f3dfe65e4e87ee4276Jonathan Koren menuView.getChildAt(0).getContentDescription(); 452c40f445372d08cc251ee70f3dfe65e4e87ee4276Jonathan Koren } 453c40f445372d08cc251ee70f3dfe65e4e87ee4276Jonathan Koren 45469557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas private void checkAndVerifyExclusiveItem(final Menu menu, final int id) throws Throwable { 45569557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas menu.findItem(id).setChecked(true); 45669557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas for (int i = 0; i < menu.size(); i++) { 45769557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas final MenuItem item = menu.getItem(i); 45869557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas if (item.getItemId() == id) { 45969557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas assertTrue(item.isChecked()); 46069557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas } else { 46169557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas assertFalse(item.isChecked()); 46269557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas } 46369557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas } 46469557a3a037e4124ecbc98560e84fa89472b3bf4Aurimas Liutikas } 465e17fd0d6c2f79ad00d6d07e88f60d53e5b85a891Aurimas Liutikas} 466