GridLayoutManagerBaseConfigSetTest.java revision 4143554adb9b31b700b6876a251a64419e6111e2
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.support.v7.widget; 18 19import org.junit.Test; 20import org.junit.runner.RunWith; 21import org.junit.runners.Parameterized; 22import android.support.v7.widget.BaseGridLayoutManagerTest.Config; 23import android.util.Log; 24import android.view.View; 25import android.view.ViewGroup; 26 27import java.util.ArrayList; 28import java.util.Arrays; 29import java.util.BitSet; 30import java.util.List; 31 32import static android.support.v7.widget.LinearLayoutManager.HORIZONTAL; 33import static android.support.v7.widget.LinearLayoutManager.VERTICAL; 34import static org.junit.Assert.assertEquals; 35import static org.junit.Assert.assertNotNull; 36import static org.junit.Assert.assertSame; 37import static org.junit.Assert.assertTrue; 38 39@RunWith(Parameterized.class) 40public class GridLayoutManagerBaseConfigSetTest extends BaseGridLayoutManagerTest { 41 @Parameterized.Parameters(name = "{0}") 42 public static List<Config> params() { 43 return createBaseVariations(); 44 } 45 46 private final Config mConfig; 47 48 public GridLayoutManagerBaseConfigSetTest(Config config) { 49 mConfig = config; 50 } 51 52 @Test 53 public void scrollBackAndPreservePositions() throws Throwable { 54 Config config = (Config) mConfig.clone(); 55 config.mItemCount = 150; 56 scrollBackAndPreservePositionsTest(config); 57 } 58 59 public void scrollBackAndPreservePositionsTest(final Config config) throws Throwable { 60 final RecyclerView rv = setupBasic(config); 61 for (int i = 1; i < mAdapter.getItemCount(); i += config.mSpanCount + 2) { 62 mAdapter.setFullSpan(i); 63 } 64 waitForFirstLayout(rv); 65 final int[] globalPositions = new int[mAdapter.getItemCount()]; 66 Arrays.fill(globalPositions, Integer.MIN_VALUE); 67 final int scrollStep = (mGlm.mOrientationHelper.getTotalSpace() / 20) 68 * (config.mReverseLayout ? -1 : 1); 69 final String logPrefix = config.toString(); 70 final int[] globalPos = new int[1]; 71 runTestOnUiThread(new Runnable() { 72 @Override 73 public void run() { 74 assertSame("test sanity", mRecyclerView, rv); 75 int globalScrollPosition = 0; 76 int visited = 0; 77 while (visited < mAdapter.getItemCount()) { 78 for (int i = 0; i < mRecyclerView.getChildCount(); i++) { 79 View child = mRecyclerView.getChildAt(i); 80 final int pos = mRecyclerView.getChildLayoutPosition(child); 81 if (globalPositions[pos] != Integer.MIN_VALUE) { 82 continue; 83 } 84 visited++; 85 GridLayoutManager.LayoutParams lp = (GridLayoutManager.LayoutParams) 86 child.getLayoutParams(); 87 if (config.mReverseLayout) { 88 globalPositions[pos] = globalScrollPosition + 89 mGlm.mOrientationHelper.getDecoratedEnd(child); 90 } else { 91 globalPositions[pos] = globalScrollPosition + 92 mGlm.mOrientationHelper.getDecoratedStart(child); 93 } 94 assertEquals(logPrefix + " span index should match", 95 mGlm.getSpanSizeLookup().getSpanIndex(pos, mGlm.getSpanCount()), 96 lp.getSpanIndex()); 97 } 98 int scrolled = mGlm.scrollBy(scrollStep, 99 mRecyclerView.mRecycler, mRecyclerView.mState); 100 globalScrollPosition += scrolled; 101 if (scrolled == 0) { 102 assertEquals( 103 logPrefix + " If scroll is complete, all views should be visited", 104 visited, mAdapter.getItemCount()); 105 } 106 } 107 if (DEBUG) { 108 Log.d(TAG, "done recording positions " + Arrays.toString(globalPositions)); 109 } 110 globalPos[0] = globalScrollPosition; 111 } 112 }); 113 checkForMainThreadException(); 114 // test sanity, ensure scroll happened 115 runTestOnUiThread(new Runnable() { 116 @Override 117 public void run() { 118 final int childCount = mGlm.getChildCount(); 119 final BitSet expectedPositions = new BitSet(); 120 for (int i = 0; i < childCount; i ++) { 121 expectedPositions.set(mAdapter.getItemCount() - i - 1); 122 } 123 for (int i = 0; i <childCount; i ++) { 124 final View view = mGlm.getChildAt(i); 125 int position = mGlm.getPosition(view); 126 assertTrue("child position should be in last page", expectedPositions.get(position)); 127 } 128 } 129 }); 130 getInstrumentation().waitForIdleSync(); 131 runTestOnUiThread(new Runnable() { 132 @Override 133 public void run() { 134 int globalScrollPosition = globalPos[0]; 135 // now scroll back and make sure global positions match 136 BitSet shouldTest = new BitSet(mAdapter.getItemCount()); 137 shouldTest.set(0, mAdapter.getItemCount() - 1, true); 138 String assertPrefix = config 139 + " global pos must match when scrolling in reverse for position "; 140 int scrollAmount = Integer.MAX_VALUE; 141 while (!shouldTest.isEmpty() && scrollAmount != 0) { 142 for (int i = 0; i < mRecyclerView.getChildCount(); i++) { 143 View child = mRecyclerView.getChildAt(i); 144 int pos = mRecyclerView.getChildLayoutPosition(child); 145 if (!shouldTest.get(pos)) { 146 continue; 147 } 148 GridLayoutManager.LayoutParams lp = (GridLayoutManager.LayoutParams) 149 child.getLayoutParams(); 150 shouldTest.clear(pos); 151 int globalPos; 152 if (config.mReverseLayout) { 153 globalPos = globalScrollPosition + 154 mGlm.mOrientationHelper.getDecoratedEnd(child); 155 } else { 156 globalPos = globalScrollPosition + 157 mGlm.mOrientationHelper.getDecoratedStart(child); 158 } 159 assertEquals(assertPrefix + pos, 160 globalPositions[pos], globalPos); 161 assertEquals("span index should match", 162 mGlm.getSpanSizeLookup().getSpanIndex(pos, mGlm.getSpanCount()), 163 lp.getSpanIndex()); 164 } 165 scrollAmount = mGlm.scrollBy(-scrollStep, 166 mRecyclerView.mRecycler, mRecyclerView.mState); 167 globalScrollPosition += scrollAmount; 168 } 169 assertTrue("all views should be seen", shouldTest.isEmpty()); 170 } 171 }); 172 checkForMainThreadException(); 173 } 174} 175