1123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov/* 2123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov * Copyright (C) 2016 The Android Open Source Project 3123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov * 4123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov * Licensed under the Apache License, Version 2.0 (the "License"); 5123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov * you may not use this file except in compliance with the License. 6123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov * You may obtain a copy of the License at 7123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov * 8123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov * http://www.apache.org/licenses/LICENSE-2.0 9123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov * 10123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov * Unless required by applicable law or agreed to in writing, software 11123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov * distributed under the License is distributed on an "AS IS" BASIS, 12123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov * See the License for the specific language governing permissions and 14123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov * limitations under the License. 15123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov */ 16123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 17123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikovpackage android.support.design.widget; 18123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 19bb3740d273d4b5108ab63f6d264466250a197e5bChris Banesimport android.os.SystemClock; 20123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikovimport android.support.annotation.LayoutRes; 21123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikovimport android.support.annotation.StringRes; 22123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikovimport android.support.design.test.R; 23123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikovimport android.support.design.testutils.Cheeses; 24c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikovimport android.test.suitebuilder.annotation.LargeTest; 25123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikovimport android.test.suitebuilder.annotation.MediumTest; 26123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikovimport org.junit.Test; 27123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 28123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikovimport static android.support.design.testutils.TestUtilsActions.addTabs; 29123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikovimport static android.support.test.espresso.Espresso.onView; 30123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikovimport static android.support.test.espresso.matcher.ViewMatchers.withId; 31123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikovimport static org.junit.Assert.assertEquals; 32123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 33123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov@MediumTest 34123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikovpublic class AppBarWithToolbarAndTabsTest extends AppBarLayoutBaseTest { 35123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov private TabLayout mTabLayout; 36123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 37123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov @Override 38123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov protected void configureContent(@LayoutRes int layoutResId, @StringRes int titleResId) { 39123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov super.configureContent(layoutResId, titleResId); 40123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 41123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov mTabLayout = (TabLayout) mAppBar.findViewById(R.id.tabs); 42c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov String[] tabTitles = new String[5]; 43c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov System.arraycopy(Cheeses.sCheeseStrings, 0, tabTitles, 0, 5); 44c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov onView(withId(R.id.tabs)).perform(addTabs(tabTitles)); 45123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov } 46123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 47123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov @Test 48123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov public void testScrollingToolbarAndScrollingTabs() { 49123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov configureContent(R.layout.design_appbar_toolbar_scroll_tabs_scroll, 50123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov R.string.design_appbar_toolbar_scroll_tabs_scroll); 51123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 52123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov final int[] appbarOnScreenXY = new int[2]; 53123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov final int[] coordinatorLayoutOnScreenXY = new int[2]; 54123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov mAppBar.getLocationOnScreen(appbarOnScreenXY); 55123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov mCoordinatorLayout.getLocationOnScreen(coordinatorLayoutOnScreenXY); 56123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 57123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov final int originalAppbarTop = appbarOnScreenXY[1]; 58123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov final int originalAppbarBottom = appbarOnScreenXY[1] + mAppBar.getHeight(); 59123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov final int centerX = appbarOnScreenXY[0] + mAppBar.getWidth() / 2; 60123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 61123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov final int toolbarHeight = mToolbar.getHeight(); 62123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov final int tabsHeight = mTabLayout.getHeight(); 63123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov final int appbarHeight = mAppBar.getHeight(); 64123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov final int longSwipeAmount = 3 * appbarHeight / 2; 65123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov final int shortSwipeAmount = toolbarHeight; 66123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 67b539fd57119c80c2b24d3b3f599e131f9aeb17ddChris Banes // Perform a swipe-up gesture across the horizontal center of the screen, starting from 68b539fd57119c80c2b24d3b3f599e131f9aeb17ddChris Banes // just below the AppBarLayout 69c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov performVerticalSwipeUpGesture( 70123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov R.id.coordinator_layout, 71123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov centerX, 72b539fd57119c80c2b24d3b3f599e131f9aeb17ddChris Banes originalAppbarBottom + 20, 73123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov longSwipeAmount); 74123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 75123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov mAppBar.getLocationOnScreen(appbarOnScreenXY); 76123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // At this point the app bar should not be visually "present" on the screen, with its bottom 77123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // edge aligned with the system status bar. Allow for off-by-a-pixel margin of error. 78123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov assertEquals(originalAppbarTop, appbarOnScreenXY[1] + appbarHeight, 1); 791a8e4886abbc35e479cddb7b4acd601cede2fd8aChris Banes assertAppBarElevation(mDefaultElevationValue); 80123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 81123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // Perform another swipe-up gesture 82c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov performVerticalSwipeUpGesture( 83123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov R.id.coordinator_layout, 84123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov centerX, 85123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov originalAppbarBottom, 86123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov shortSwipeAmount); 87123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 88123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov mAppBar.getLocationOnScreen(appbarOnScreenXY); 89123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // At this point the app bar should still be off the screen. Allow for off-by-a-pixel 90123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // margin of error. 91123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov assertEquals(originalAppbarTop, appbarOnScreenXY[1] + appbarHeight, 1); 921a8e4886abbc35e479cddb7b4acd601cede2fd8aChris Banes assertAppBarElevation(mDefaultElevationValue); 93123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 94123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // Perform a long swipe-down gesture across the horizontal center of the screen. 95123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // Note that the swipe down is a bit longer than the swipe up to fully bring down 96123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // the scrolled-away toolbar and tab layout 97123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov performVerticalSwipeDownGesture( 98123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov R.id.coordinator_layout, 99123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov centerX, 100123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov originalAppbarBottom, 101123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov longSwipeAmount * 3 / 2); 102123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 103123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov mAppBar.getLocationOnScreen(appbarOnScreenXY); 104123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // At this point the app bar should be visually snapped below the system status bar as it 105123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // in scrolling mode and we've swiped down. Allow for off-by-a-pixel 106123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // margin of error. 107123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov assertEquals(originalAppbarTop, appbarOnScreenXY[1], 1); 108123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov assertEquals(originalAppbarBottom, appbarOnScreenXY[1] + appbarHeight, 1); 1091a8e4886abbc35e479cddb7b4acd601cede2fd8aChris Banes assertAppBarElevation(mDefaultElevationValue); 110123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 111123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // Perform another swipe-down gesture across the horizontal center of the screen. 112123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov performVerticalSwipeDownGesture( 113123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov R.id.coordinator_layout, 114123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov centerX, 115123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov originalAppbarBottom, 116123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov longSwipeAmount); 117123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 118123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov mAppBar.getLocationOnScreen(appbarOnScreenXY); 119123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // At this point the app bar should be in its original position. 120123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // Allow for off-by-a-pixel margin of error. 121123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov assertEquals(originalAppbarTop, appbarOnScreenXY[1], 1); 122123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov assertEquals(originalAppbarBottom, appbarOnScreenXY[1] + appbarHeight, 1); 1231a8e4886abbc35e479cddb7b4acd601cede2fd8aChris Banes assertAppBarElevation(mDefaultElevationValue); 124123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 125123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // Perform yet another swipe-down gesture across the horizontal center of the screen. 126123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov performVerticalSwipeDownGesture( 127123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov R.id.coordinator_layout, 128123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov centerX, 129123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov originalAppbarBottom, 130123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov longSwipeAmount); 131123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 132123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov mAppBar.getLocationOnScreen(appbarOnScreenXY); 133123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // At this point the app bar should still be in its original position. 134123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // Allow for off-by-a-pixel margin of error. 135123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov assertEquals(originalAppbarTop, appbarOnScreenXY[1], 1); 136123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov assertEquals(originalAppbarBottom, appbarOnScreenXY[1] + appbarHeight, 1); 1371a8e4886abbc35e479cddb7b4acd601cede2fd8aChris Banes assertAppBarElevation(mDefaultElevationValue); 138123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov } 139123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 140123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov @Test 141c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov public void testScrollingToolbarAndPinnedTabs() { 142123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov configureContent(R.layout.design_appbar_toolbar_scroll_tabs_pinned, 143123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov R.string.design_appbar_toolbar_scroll_tabs_pin); 144123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 145123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov final int[] appbarOnScreenXY = new int[2]; 146123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov final int[] coordinatorLayoutOnScreenXY = new int[2]; 147123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov mAppBar.getLocationOnScreen(appbarOnScreenXY); 148123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov mCoordinatorLayout.getLocationOnScreen(coordinatorLayoutOnScreenXY); 149123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 150123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov final int originalAppbarTop = appbarOnScreenXY[1]; 151123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov final int originalAppbarBottom = appbarOnScreenXY[1] + mAppBar.getHeight(); 152123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov final int centerX = appbarOnScreenXY[0] + mAppBar.getWidth() / 2; 153123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 154123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov final int toolbarHeight = mToolbar.getHeight(); 155123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov final int tabsHeight = mTabLayout.getHeight(); 156123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov final int appbarHeight = mAppBar.getHeight(); 157123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov final int longSwipeAmount = 3 * appbarHeight / 2; 158123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov final int shortSwipeAmount = toolbarHeight; 159123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 160b539fd57119c80c2b24d3b3f599e131f9aeb17ddChris Banes // Perform a swipe-up gesture across the horizontal center of the screen, starting from 161b539fd57119c80c2b24d3b3f599e131f9aeb17ddChris Banes // just below the AppBarLayout 162c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov performVerticalSwipeUpGesture( 163123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov R.id.coordinator_layout, 164123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov centerX, 165b539fd57119c80c2b24d3b3f599e131f9aeb17ddChris Banes originalAppbarBottom + 20, 166123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov longSwipeAmount); 167123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 168123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov mAppBar.getLocationOnScreen(appbarOnScreenXY); 169123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // At this point the tab bar should be visually snapped below the system status bar. 170123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // Allow for off-by-a-pixel margin of error. 171123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov assertEquals(originalAppbarTop + tabsHeight, appbarOnScreenXY[1] + appbarHeight, 1); 1721a8e4886abbc35e479cddb7b4acd601cede2fd8aChris Banes assertAppBarElevation(mDefaultElevationValue); 173123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 174123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // Perform another swipe-up gesture 175c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov performVerticalSwipeUpGesture( 176123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov R.id.coordinator_layout, 177123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov centerX, 178123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov originalAppbarBottom, 179123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov shortSwipeAmount); 180123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 181123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov mAppBar.getLocationOnScreen(appbarOnScreenXY); 182123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // At this point the tab bar should still be visually snapped below the system status bar 183123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // as it is in the pinned mode. Allow for off-by-a-pixel margin of error. 184123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov assertEquals(originalAppbarTop + tabsHeight, appbarOnScreenXY[1] + appbarHeight, 1); 1851a8e4886abbc35e479cddb7b4acd601cede2fd8aChris Banes assertAppBarElevation(mDefaultElevationValue); 186123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 187123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // Perform a short swipe-down gesture across the horizontal center of the screen. 188123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // Note that the swipe down is a bit longer than the swipe up to fully bring down 189123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // the scrolled-away toolbar and tab layout 190123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov performVerticalSwipeDownGesture( 191123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov R.id.coordinator_layout, 192123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov centerX, 193123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov originalAppbarBottom - shortSwipeAmount, 194123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 3 * shortSwipeAmount / 2); 195123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 196123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov mAppBar.getLocationOnScreen(appbarOnScreenXY); 197123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // At this point the app bar should be in its original position as it 198123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // in scrolling mode and we've swiped down. Allow for off-by-a-pixel 199123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // margin of error. 200123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov assertEquals(originalAppbarTop, appbarOnScreenXY[1], 1); 201123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov assertEquals(originalAppbarBottom, appbarOnScreenXY[1] + appbarHeight, 1); 2021a8e4886abbc35e479cddb7b4acd601cede2fd8aChris Banes assertAppBarElevation(mDefaultElevationValue); 203123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 204123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // Perform another swipe-down gesture across the horizontal center of the screen. 205123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov performVerticalSwipeDownGesture( 206123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov R.id.coordinator_layout, 207123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov centerX, 208123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov originalAppbarBottom, 209123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov longSwipeAmount); 210123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 211123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov mAppBar.getLocationOnScreen(appbarOnScreenXY); 212123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // At this point the app bar should be in its original position. 213123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // Allow for off-by-a-pixel margin of error. 214123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov assertEquals(originalAppbarTop, appbarOnScreenXY[1], 1); 215123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov assertEquals(originalAppbarBottom, appbarOnScreenXY[1] + appbarHeight, 1); 2161a8e4886abbc35e479cddb7b4acd601cede2fd8aChris Banes assertAppBarElevation(mDefaultElevationValue); 217123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 218123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // Perform yet another swipe-down gesture across the horizontal center of the screen. 219123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov performVerticalSwipeDownGesture( 220123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov R.id.coordinator_layout, 221123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov centerX, 222123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov originalAppbarBottom, 223123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov longSwipeAmount); 224123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 225123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov mAppBar.getLocationOnScreen(appbarOnScreenXY); 226123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // At this point the app bar should still be in its original position. 227123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov // Allow for off-by-a-pixel margin of error. 228123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov assertEquals(originalAppbarTop, appbarOnScreenXY[1], 1); 229123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov assertEquals(originalAppbarBottom, appbarOnScreenXY[1] + appbarHeight, 1); 2301a8e4886abbc35e479cddb7b4acd601cede2fd8aChris Banes assertAppBarElevation(mDefaultElevationValue); 231123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov } 232123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov 233c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov @LargeTest 234c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov @Test 235c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov public void testSnappingToolbarAndSnappingTabs() { 236c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov configureContent(R.layout.design_appbar_toolbar_scroll_tabs_scroll_snap, 237c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov R.string.design_appbar_toolbar_scroll_tabs_scroll_snap); 238c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 239c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov final int[] appbarOnScreenXY = new int[2]; 240c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov final int[] coordinatorLayoutOnScreenXY = new int[2]; 241c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov mAppBar.getLocationOnScreen(appbarOnScreenXY); 242c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov mCoordinatorLayout.getLocationOnScreen(coordinatorLayoutOnScreenXY); 243c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 244c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov final int originalAppbarTop = appbarOnScreenXY[1]; 245c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov final int originalAppbarBottom = appbarOnScreenXY[1] + mAppBar.getHeight(); 246c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov final int centerX = appbarOnScreenXY[0] + mAppBar.getWidth() / 2; 247c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 248c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov final int toolbarHeight = mToolbar.getHeight(); 249c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov final int tabsHeight = mTabLayout.getHeight(); 250c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov final int appbarHeight = mAppBar.getHeight(); 251c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 252c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // Since AppBarLayout doesn't expose a way to track snap animations, the three possible 253c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // options are 254c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // a) track how vertical offsets and invalidation is propagated through the 255c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // view hierarchy and wait until there are no more events of that kind 256c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // b) run a dummy Espresso action that waits until the main thread is idle 257c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // c) sleep for a hardcoded period of time to "wait" until the snap animation is done 258c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // In this test method we go with option b) 259c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 260c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // Perform a swipe-up gesture across the horizontal center of the screen. The amount 261c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // of swipe is 25% of the toolbar height and we expect the snap behavior to "move" 262c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // the app bar back to its original position. 263c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov performVerticalSwipeUpGesture( 264c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov R.id.coordinator_layout, 265c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov centerX, 266c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov originalAppbarBottom + toolbarHeight, 267c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov toolbarHeight / 4); 268c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 269c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // Wait for the snap animation to be done 270bb3740d273d4b5108ab63f6d264466250a197e5bChris Banes waitForSnapAnimationToFinish(); 271c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 272c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov mAppBar.getLocationOnScreen(appbarOnScreenXY); 273c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // At this point the app bar should be in its original position as it 274c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // in snapping mode and we haven't swiped "enough". Allow for off-by-a-pixel 275c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // margin of error. 276c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov assertEquals(originalAppbarTop, appbarOnScreenXY[1], 1); 277c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov assertEquals(originalAppbarBottom, appbarOnScreenXY[1] + appbarHeight, 1); 2781a8e4886abbc35e479cddb7b4acd601cede2fd8aChris Banes assertAppBarElevation(mDefaultElevationValue); 279c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 280c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // Perform a slightly longer swipe-up gesture, this time by 75% of the toolbar height. 281c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // We expect the snap behavior to move the app bar to snap the tab layout below the 282c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // system status bar. 283c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov performVerticalSwipeUpGesture( 284c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov R.id.coordinator_layout, 285c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov centerX, 286c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov originalAppbarBottom + toolbarHeight, 287c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 3 * toolbarHeight / 4); 288c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 289c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // Wait for the snap animation to be done 290bb3740d273d4b5108ab63f6d264466250a197e5bChris Banes waitForSnapAnimationToFinish(); 291c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 292c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov mAppBar.getLocationOnScreen(appbarOnScreenXY); 293c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // At this point the app bar should "snap" the toolbar away and align the tab layout below 294c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // the system status bar. Allow for off-by-a-pixel margin of error. 295c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov assertEquals(originalAppbarTop + tabsHeight, appbarOnScreenXY[1] + appbarHeight, 1); 2961a8e4886abbc35e479cddb7b4acd601cede2fd8aChris Banes assertAppBarElevation(mDefaultElevationValue); 297c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 298c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // Perform a short swipe-up gesture, this time by 25% of the tab layout height. We expect 299c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // snap behavior to move the app bar back to snap the tab layout below the system status 300c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // bar. 301c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov performVerticalSwipeUpGesture( 302c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov R.id.coordinator_layout, 303c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov centerX, 304c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov originalAppbarBottom + toolbarHeight, 305c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov tabsHeight / 4); 306c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 307c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // Wait for the snap animation to be done 308bb3740d273d4b5108ab63f6d264466250a197e5bChris Banes waitForSnapAnimationToFinish(); 309c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 310c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov mAppBar.getLocationOnScreen(appbarOnScreenXY); 311c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // At this point the app bar should "snap" back to align the tab layout below 312c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // the system status bar. Allow for off-by-a-pixel margin of error. 313c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov assertEquals(originalAppbarTop + tabsHeight, appbarOnScreenXY[1] + appbarHeight, 1); 3141a8e4886abbc35e479cddb7b4acd601cede2fd8aChris Banes assertAppBarElevation(mDefaultElevationValue); 315c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 316c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // Perform a longer swipe-up gesture, this time by 75% of the tab layout height. We expect 317c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // snap behavior to move the app bar fully away from the screen. 318c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov performVerticalSwipeUpGesture( 319c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov R.id.coordinator_layout, 320c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov centerX, 321c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov originalAppbarBottom + toolbarHeight, 322c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 3 * tabsHeight / 4); 323c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 324c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // Wait for the snap animation to be done 325bb3740d273d4b5108ab63f6d264466250a197e5bChris Banes waitForSnapAnimationToFinish(); 326c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 327c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov mAppBar.getLocationOnScreen(appbarOnScreenXY); 328c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // At this point the app bar should not be visually "present" on the screen, with its bottom 329c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // edge aligned with the system status bar. Allow for off-by-a-pixel margin of error. 330c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov assertEquals(originalAppbarTop, appbarOnScreenXY[1] + appbarHeight, 1); 3311a8e4886abbc35e479cddb7b4acd601cede2fd8aChris Banes assertAppBarElevation(mDefaultElevationValue); 332c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 333c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // Perform a short swipe-down gesture by 25% of the tab layout height. We expect 334c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // snap behavior to move the app bar back fully away from the screen. 335c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov performVerticalSwipeDownGesture( 336c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov R.id.coordinator_layout, 337c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov centerX, 338c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov originalAppbarBottom + toolbarHeight, 339c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov tabsHeight / 4); 340c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 341c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // Wait for the snap animation to be done 342bb3740d273d4b5108ab63f6d264466250a197e5bChris Banes waitForSnapAnimationToFinish(); 343c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 344c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov mAppBar.getLocationOnScreen(appbarOnScreenXY); 345c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // At this point the app bar should still not be visually "present" on the screen, with 346c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // its bottom edge aligned with the system status bar. Allow for off-by-a-pixel margin 347c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // of error. 348c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov assertEquals(originalAppbarTop, appbarOnScreenXY[1] + appbarHeight, 1); 3491a8e4886abbc35e479cddb7b4acd601cede2fd8aChris Banes assertAppBarElevation(mDefaultElevationValue); 350c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 351c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // Perform a longer swipe-up gesture, this time by 75% of the tab layout height. We expect 352c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // snap behavior to move the app bar to snap the tab layout below the system status 353c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // bar. 354c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov performVerticalSwipeDownGesture( 355c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov R.id.coordinator_layout, 356c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov centerX, 357c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov originalAppbarBottom + toolbarHeight, 358c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 3 * tabsHeight / 4); 359c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 360c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // Wait for the snap animation to be done 361bb3740d273d4b5108ab63f6d264466250a197e5bChris Banes waitForSnapAnimationToFinish(); 362c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 363c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov mAppBar.getLocationOnScreen(appbarOnScreenXY); 364c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // At this point the app bar should "snap" the toolbar away and align the tab layout below 365c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // the system status bar. Allow for off-by-a-pixel margin of error. 366c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov assertEquals(originalAppbarTop + tabsHeight, appbarOnScreenXY[1] + appbarHeight, 1); 3671a8e4886abbc35e479cddb7b4acd601cede2fd8aChris Banes assertAppBarElevation(mDefaultElevationValue); 368c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 369c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // Perform a short swipe-down gesture by 25% of the toolbar height. We expect 370c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // snap behavior to align the tab layout below the system status bar 371c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov performVerticalSwipeDownGesture( 372c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov R.id.coordinator_layout, 373c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov centerX, 374c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov originalAppbarBottom + toolbarHeight, 375c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov toolbarHeight / 4); 376c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 377c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // Wait for the snap animation to be done 378bb3740d273d4b5108ab63f6d264466250a197e5bChris Banes waitForSnapAnimationToFinish(); 379c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 380c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov mAppBar.getLocationOnScreen(appbarOnScreenXY); 381c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // At this point the app bar should still align the tab layout below 382c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // the system status bar. Allow for off-by-a-pixel margin of error. 383c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov assertEquals(originalAppbarTop + tabsHeight, appbarOnScreenXY[1] + appbarHeight, 1); 3841a8e4886abbc35e479cddb7b4acd601cede2fd8aChris Banes assertAppBarElevation(mDefaultElevationValue); 385c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 386c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // Perform a longer swipe-up gesture, this time by 75% of the toolbar height. We expect 387c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // snap behavior to move the app bar back to its original place (fully visible). 388c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov performVerticalSwipeDownGesture( 389c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov R.id.coordinator_layout, 390c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov centerX, 391c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov originalAppbarBottom + toolbarHeight, 392c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 3 * tabsHeight / 4); 393c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 394c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // Wait for the snap animation to be done 395bb3740d273d4b5108ab63f6d264466250a197e5bChris Banes waitForSnapAnimationToFinish(); 396c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov 397c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov mAppBar.getLocationOnScreen(appbarOnScreenXY); 398c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // At this point the app bar should be in its original position. 399c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov // Allow for off-by-a-pixel margin of error. 400c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov assertEquals(originalAppbarTop, appbarOnScreenXY[1], 1); 401c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov assertEquals(originalAppbarBottom, appbarOnScreenXY[1] + appbarHeight, 1); 4021a8e4886abbc35e479cddb7b4acd601cede2fd8aChris Banes assertAppBarElevation(mDefaultElevationValue); 403c530cc115fddab8e1d9645b322424dd45f9ecd0dKirill Grouchnikov } 404bb3740d273d4b5108ab63f6d264466250a197e5bChris Banes 405bb3740d273d4b5108ab63f6d264466250a197e5bChris Banes private void waitForSnapAnimationToFinish() { 406bb3740d273d4b5108ab63f6d264466250a197e5bChris Banes final AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) 407bb3740d273d4b5108ab63f6d264466250a197e5bChris Banes ((CoordinatorLayout.LayoutParams) mAppBar.getLayoutParams()).getBehavior(); 408bb3740d273d4b5108ab63f6d264466250a197e5bChris Banes while (behavior.isOffsetAnimatorRunning()) { 409bb3740d273d4b5108ab63f6d264466250a197e5bChris Banes SystemClock.sleep(16); 410bb3740d273d4b5108ab63f6d264466250a197e5bChris Banes } 411bb3740d273d4b5108ab63f6d264466250a197e5bChris Banes } 412123544eaa855a7734be92dd35901233a222f64a8Kirill Grouchnikov} 413