18cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar/* 28cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar * Copyright (C) 2016 The Android Open Source Project 38cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar * 48cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 58cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar * you may not use this file except in compliance with the License. 68cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar * You may obtain a copy of the License at 78cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar * 88cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 98cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar * 108cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar * Unless required by applicable law or agreed to in writing, software 118cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 128cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar * See the License for the specific language governing permissions and 148cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar * limitations under the License. 158cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar */ 168cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar 178cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyarpackage android.support.v7.widget; 188cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar 198cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyarimport static android.view.View.MeasureSpec.AT_MOST; 208cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyarimport static android.view.View.MeasureSpec.EXACTLY; 218cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyarimport static android.view.View.MeasureSpec.makeMeasureSpec; 228cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar 238cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyarimport static org.hamcrest.CoreMatchers.is; 248cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyarimport static org.hamcrest.CoreMatchers.notNullValue; 258cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyarimport static org.hamcrest.MatcherAssert.assertThat; 268cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar 278cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyarimport android.graphics.Rect; 28754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport android.support.test.filters.MediumTest; 298cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyarimport android.support.test.runner.AndroidJUnit4; 308cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyarimport android.view.View; 318cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar 328cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyarimport org.junit.Test; 338cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyarimport org.junit.runner.RunWith; 348cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar 358cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar/** 368cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar * Tests scroll to position with wrap content to make sure that LayoutManagers can keep track of 378cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar * the position if layout is called multiple times. 388cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar */ 398cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar@MediumTest 408cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar@RunWith(AndroidJUnit4.class) 418cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyarpublic class ScrollToPositionWithAutoMeasure extends BaseRecyclerViewInstrumentationTest { 428cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar @Test 438cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar public void testLinearLayoutManager() throws Throwable { 448cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar LinearLayoutManager llm = new LinearLayoutManager(getActivity()); 458cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar llm.ensureLayoutState(); 468cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar test(llm, llm.mOrientationHelper); 478cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar } 488cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar 498cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar @Test 508cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar public void testGridLayoutManager() throws Throwable { 518cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar GridLayoutManager glm = new GridLayoutManager(getActivity(), 3); 528cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar glm.ensureLayoutState(); 538cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar test(glm, glm.mOrientationHelper); 548cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar } 558cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar 568cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar @Test 578cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar public void testStaggeredGridLayoutManager() throws Throwable { 588cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar StaggeredGridLayoutManager sglm = new StaggeredGridLayoutManager(3, 598cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar StaggeredGridLayoutManager.VERTICAL); 608cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar test(sglm, sglm.mPrimaryOrientation); 618cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar } 628cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar 638cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar public void test(final RecyclerView.LayoutManager llm, 648cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar final OrientationHelper orientationHelper) throws Throwable { 658cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar final RecyclerView recyclerView = new RecyclerView(getActivity()); 668cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar recyclerView.setLayoutManager(llm); 678cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar recyclerView.setAdapter(new TestAdapter(1000)); 688cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar setRecyclerView(recyclerView); 698cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar getInstrumentation().waitForIdleSync(); 708cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar assertThat("Test sanity", recyclerView.getChildCount() > 0, is(true)); 7142e7d6fafcde7bfe261dd7d8d75ee53ca0cd6790Aurimas Liutikas mActivityRule.runOnUiThread(new Runnable() { 728cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar @Override 738cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar public void run() { 748cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar View lastChild = llm.getChildAt(llm.getChildCount() - 1); 758cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar int lastChildPos = recyclerView.getChildAdapterPosition(lastChild); 768cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar int targetPos = lastChildPos * 2; 778cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar llm.scrollToPosition(targetPos); 788cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar recyclerView.measure( 798cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar makeMeasureSpec(recyclerView.getWidth(), EXACTLY), 808cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar makeMeasureSpec(recyclerView.getHeight(), AT_MOST)); 818cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar assertThat(recyclerView.findViewHolderForAdapterPosition(targetPos), 828cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar notNullValue()); 838cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar // make sure it is still visible from top at least 848cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar int size = orientationHelper.getDecoratedMeasurement( 858cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar recyclerView.findViewHolderForAdapterPosition(targetPos).itemView); 868cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar recyclerView.measure( 878cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar makeMeasureSpec(recyclerView.getWidth(), EXACTLY), 888cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar makeMeasureSpec(size + 1, EXACTLY)); 898cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar recyclerView.layout(0, 0, recyclerView.getMeasuredWidth(), 908cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar recyclerView.getMeasuredHeight()); 918cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar assertThat(recyclerView.findViewHolderForAdapterPosition(targetPos), 928cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar notNullValue()); 938cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar RecyclerView.ViewHolder viewHolder = 948cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar recyclerView.findViewHolderForAdapterPosition(targetPos); 958cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar assertThat(viewHolder, notNullValue()); 968cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar Rect viewBounds = new Rect(); 978cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar llm.getDecoratedBoundsWithMargins(viewHolder.itemView, viewBounds); 988cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar Rect rvBounds = new Rect(0, 0, llm.getWidth(), llm.getHeight()); 999aae13b01e2a00d892ab82677f613bcc6e380baeYigit Boyar assertThat(rvBounds + " vs " + viewBounds, rvBounds.contains(viewBounds), is(true)); 1008cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar } 1018cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar }); 1028cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar } 1038cf399b2e813234a1a603df3575c2dcdfa38dc9eYigit Boyar}