GridLayoutManagerTest.java revision 42e9353bb9eb2747247e30e3612b227945acfd16
173304eff156157f62075215e795e774803a6f96aYigit Boyar/* 273304eff156157f62075215e795e774803a6f96aYigit Boyar * Copyright (C) 2014 The Android Open Source Project 373304eff156157f62075215e795e774803a6f96aYigit Boyar * 473304eff156157f62075215e795e774803a6f96aYigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 573304eff156157f62075215e795e774803a6f96aYigit Boyar * you may not use this file except in compliance with the License. 673304eff156157f62075215e795e774803a6f96aYigit Boyar * You may obtain a copy of the License at 773304eff156157f62075215e795e774803a6f96aYigit Boyar * 873304eff156157f62075215e795e774803a6f96aYigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 973304eff156157f62075215e795e774803a6f96aYigit Boyar * 1073304eff156157f62075215e795e774803a6f96aYigit Boyar * Unless required by applicable law or agreed to in writing, software 1173304eff156157f62075215e795e774803a6f96aYigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 1273304eff156157f62075215e795e774803a6f96aYigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1373304eff156157f62075215e795e774803a6f96aYigit Boyar * See the License for the specific language governing permissions and 1473304eff156157f62075215e795e774803a6f96aYigit Boyar * limitations under the License. 1573304eff156157f62075215e795e774803a6f96aYigit Boyar */ 1673304eff156157f62075215e795e774803a6f96aYigit Boyar 1773304eff156157f62075215e795e774803a6f96aYigit Boyarpackage android.support.v7.widget; 1873304eff156157f62075215e795e774803a6f96aYigit Boyar 19061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyarimport android.content.Context; 20a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyarimport android.support.v4.view.AccessibilityDelegateCompat; 21a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyarimport android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; 22061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyarimport android.util.Log; 23061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyarimport android.view.View; 24061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyarimport android.view.ViewGroup; 25061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 26061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyarimport java.util.ArrayList; 27061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyarimport java.util.Arrays; 28061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyarimport java.util.BitSet; 29afa0494a97687b705feb3659385578f33f697ea9Yigit Boyarimport java.util.HashMap; 30061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyarimport java.util.HashSet; 31061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyarimport java.util.List; 32afa0494a97687b705feb3659385578f33f697ea9Yigit Boyarimport java.util.Map; 33061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyarimport java.util.Set; 34061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyarimport java.util.concurrent.CountDownLatch; 35061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 36061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyarimport static android.support.v7.widget.LinearLayoutManager.HORIZONTAL; 37061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyarimport static android.support.v7.widget.LinearLayoutManager.VERTICAL; 38061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyarimport static java.util.concurrent.TimeUnit.SECONDS; 39061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 4073304eff156157f62075215e795e774803a6f96aYigit Boyarpublic class GridLayoutManagerTest extends BaseRecyclerViewInstrumentationTest { 41061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 42061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar static final String TAG = "GridLayoutManagerTest"; 43061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 44061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar static final boolean DEBUG = false; 45061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 46061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar WrappedGridLayoutManager mGlm; 47061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 48061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar GridTestAdapter mAdapter; 49061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 50061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar final List<Config> mBaseVariations = new ArrayList<Config>(); 51061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 52061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar @Override 53061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar protected void setUp() throws Exception { 54061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar super.setUp(); 55061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar for (int orientation : new int[]{VERTICAL, HORIZONTAL}) { 56061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar for (boolean reverseLayout : new boolean[]{false, true}) { 57061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar for (int spanCount : new int[]{1, 3, 4}) { 58061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mBaseVariations.add(new Config(spanCount, orientation, reverseLayout)); 59061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 60061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 61061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 62061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 63061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 64061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public RecyclerView setupBasic(Config config) throws Throwable { 65061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar return setupBasic(config, new GridTestAdapter(config.mItemCount)); 66061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 67061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 68061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public RecyclerView setupBasic(Config config, GridTestAdapter testAdapter) throws Throwable { 69061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar RecyclerView recyclerView = new RecyclerView(getActivity()); 70061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mAdapter = testAdapter; 71061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mGlm = new WrappedGridLayoutManager(getActivity(), config.mSpanCount, config.mOrientation, 72061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar config.mReverseLayout); 73061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mAdapter.assignSpanSizeLookup(mGlm); 74061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar recyclerView.setAdapter(mAdapter); 75061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar recyclerView.setLayoutManager(mGlm); 76061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar return recyclerView; 77061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 78061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 79061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public void waitForFirstLayout(RecyclerView recyclerView) throws Throwable { 80061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mGlm.expectLayout(1); 81061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar setRecyclerView(recyclerView); 82061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mGlm.waitForLayout(2); 83061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 84061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 8542e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar public void testCustomWidthInHorizontal() throws Throwable { 8642e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar customSizeInScrollDirectionTest(new Config(3, HORIZONTAL, false)); 8742e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar } 8842e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar 8942e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar public void testCustomHeightInVertical() throws Throwable { 9042e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar customSizeInScrollDirectionTest(new Config(3, VERTICAL, false)); 9142e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar } 9242e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar 9342e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar public void customSizeInScrollDirectionTest(final Config config) throws Throwable { 9442e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar final int[] sizePerPosition = new int[]{3, 5, 9, 21, 3, 5, 9, 6, 9, 1}; 9542e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar final int[] expectedSizePerPosition = new int[]{9, 9, 9, 21, 3, 5, 9, 9, 9, 1}; 9642e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar final GridTestAdapter testAdapter = new GridTestAdapter(10) { 9742e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar @Override 9842e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar public void onBindViewHolder(TestViewHolder holder, 9942e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar int position) { 10042e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar super.onBindViewHolder(holder, position); 10142e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams(); 10242e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar if (layoutParams == null) { 10342e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 10442e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar ViewGroup.LayoutParams.WRAP_CONTENT); 10542e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar holder.itemView.setLayoutParams(layoutParams); 10642e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar } 10742e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar final int size = sizePerPosition[position]; 10842e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar if (config.mOrientation == HORIZONTAL) { 10942e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar layoutParams.width = size; 11042e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar } else { 11142e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar layoutParams.height = size; 11242e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar } 11342e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar } 11442e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar }; 11542e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar testAdapter.setFullSpan(3, 5); 11642e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar final RecyclerView rv = setupBasic(config, testAdapter); 11742e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar waitForFirstLayout(rv); 11842e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar 11942e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar assertTrue("[test sanity] some views should be laid out", mRecyclerView.getChildCount() > 0); 12042e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar for (int i = 0; i < mRecyclerView.getChildCount(); i++) { 12142e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar View child = mRecyclerView.getChildAt(i); 12242e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar final int size = config.mOrientation == HORIZONTAL ? child.getWidth() 12342e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar : child.getHeight(); 12442e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar assertEquals("child " + i + " should have the size specified in its layout params", 12542e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar expectedSizePerPosition[i], size); 12642e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar } 12742e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar checkForMainThreadException(); 12842e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar } 12942e9353bb9eb2747247e30e3612b227945acfd16Yigit Boyar 130061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public void testLayoutParams() throws Throwable { 131061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar layoutParamsTest(GridLayoutManager.HORIZONTAL); 132061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar removeRecyclerView(); 133061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar layoutParamsTest(GridLayoutManager.VERTICAL); 134061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 135061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 136a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar public void testHorizontalAccessibilitySpanIndices() throws Throwable { 137a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar accessibilitySpanIndicesTest(HORIZONTAL); 138a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar } 139a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar 140a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar public void testVerticalAccessibilitySpanIndices() throws Throwable { 141a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar accessibilitySpanIndicesTest(VERTICAL); 142a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar } 143a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar 144a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar public void accessibilitySpanIndicesTest(int orientation) throws Throwable { 145a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar final RecyclerView recyclerView = setupBasic(new Config(3, orientation, false)); 146a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar waitForFirstLayout(recyclerView); 147a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar final AccessibilityDelegateCompat delegateCompat = mRecyclerView 148a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar .getCompatAccessibilityDelegate().getItemDelegate(); 149a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar final AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain(); 150a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar final View chosen = recyclerView.getChildAt(recyclerView.getChildCount() - 2); 151a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar final int position = recyclerView.getChildPosition(chosen); 152a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar runTestOnUiThread(new Runnable() { 153a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar @Override 154a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar public void run() { 155a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar delegateCompat.onInitializeAccessibilityNodeInfo(chosen, info); 156a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar } 157a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar }); 158a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar GridLayoutManager.SpanSizeLookup ssl = mGlm.mSpanSizeLookup; 159a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar AccessibilityNodeInfoCompat.CollectionItemInfoCompat itemInfo = info 160a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar .getCollectionItemInfo(); 161a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar assertNotNull(itemInfo); 162a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar assertEquals("result should have span group position", 163a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar ssl.getSpanGroupIndex(position, mGlm.getSpanCount()), 164a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar orientation == HORIZONTAL ? itemInfo.getColumnIndex() : itemInfo.getRowIndex()); 165a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar assertEquals("result should have span index", 166a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar ssl.getSpanIndex(position, mGlm.getSpanCount()), 167a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar orientation == HORIZONTAL ? itemInfo.getRowIndex() : itemInfo.getColumnIndex()); 168a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar assertEquals("result should have span size", 169a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar ssl.getSpanSize(position), 170a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar orientation == HORIZONTAL ? itemInfo.getRowSpan() : itemInfo.getColumnSpan()); 171a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar } 172a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar 173afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar public GridLayoutManager.LayoutParams ensureGridLp(View view) { 174afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar ViewGroup.LayoutParams lp = view.getLayoutParams(); 175afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar GridLayoutManager.LayoutParams glp; 176afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar if (lp instanceof GridLayoutManager.LayoutParams) { 177afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar glp = (GridLayoutManager.LayoutParams) lp; 178afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar } else if (lp == null) { 179afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar glp = (GridLayoutManager.LayoutParams) mGlm 180afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar .generateDefaultLayoutParams(); 181afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar view.setLayoutParams(glp); 182afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar } else { 183afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar glp = (GridLayoutManager.LayoutParams) mGlm.generateLayoutParams(lp); 184afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar view.setLayoutParams(glp); 185afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar } 186afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar return glp; 187afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar } 188afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar 189061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public void layoutParamsTest(final int orientation) throws Throwable { 190061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar final RecyclerView rv = setupBasic(new Config(3, 100).orientation(orientation), 191061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar new GridTestAdapter(100) { 192061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar @Override 193061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public void onBindViewHolder(TestViewHolder holder, 194061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar int position) { 195061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar super.onBindViewHolder(holder, position); 196afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar GridLayoutManager.LayoutParams glp = ensureGridLp(holder.itemView); 197061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar int val = 0; 198061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar switch (position % 5) { 199061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar case 0: 200061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar val = 10; 201061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar break; 202061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar case 1: 203061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar val = 30; 204061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar break; 205061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar case 2: 206061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar val = GridLayoutManager.LayoutParams.WRAP_CONTENT; 207061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar break; 208061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar case 3: 209061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar val = GridLayoutManager.LayoutParams.FILL_PARENT; 210061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar break; 211061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar case 4: 212061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar val = 200; 213061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar break; 214061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 215061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar if (orientation == GridLayoutManager.VERTICAL) { 216061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar glp.height = val; 217061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } else { 218061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar glp.width = val; 219061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 220061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar holder.itemView.setLayoutParams(glp); 221061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 222061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar }); 223061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar waitForFirstLayout(rv); 224061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar final OrientationHelper helper = mGlm.mOrientationHelper; 225061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar final int firstRowSize = Math.max(30, getSize(mGlm.findViewByPosition(2))); 226afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar assertEquals(firstRowSize, helper.getDecoratedMeasurement(mGlm.findViewByPosition(0))); 227afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar assertEquals(firstRowSize, helper.getDecoratedMeasurement(mGlm.findViewByPosition(1))); 228afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar assertEquals(firstRowSize, helper.getDecoratedMeasurement(mGlm.findViewByPosition(2))); 229061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals(firstRowSize, getSize(mGlm.findViewByPosition(0))); 230061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals(firstRowSize, getSize(mGlm.findViewByPosition(1))); 231061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals(firstRowSize, getSize(mGlm.findViewByPosition(2))); 232061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 233061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar final int secondRowSize = Math.max(200, getSize(mGlm.findViewByPosition(3))); 234afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar assertEquals(secondRowSize, helper.getDecoratedMeasurement(mGlm.findViewByPosition(3))); 235afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar assertEquals(secondRowSize, helper.getDecoratedMeasurement(mGlm.findViewByPosition(4))); 236afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar assertEquals(secondRowSize, helper.getDecoratedMeasurement(mGlm.findViewByPosition(5))); 237061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals(secondRowSize, getSize(mGlm.findViewByPosition(3))); 238061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals(secondRowSize, getSize(mGlm.findViewByPosition(4))); 239061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals(secondRowSize, getSize(mGlm.findViewByPosition(5))); 240061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 241061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 242061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar private int getSize(View view) { 243061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar if (mGlm.getOrientation() == GridLayoutManager.HORIZONTAL) { 244061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar return view.getWidth(); 245061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 246061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar return view.getHeight(); 247061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 248061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 24973304eff156157f62075215e795e774803a6f96aYigit Boyar public void testAnchorUpdate() throws InterruptedException { 25073304eff156157f62075215e795e774803a6f96aYigit Boyar GridLayoutManager glm = new GridLayoutManager(getActivity(), 11); 25173304eff156157f62075215e795e774803a6f96aYigit Boyar final GridLayoutManager.SpanSizeLookup spanSizeLookup 25273304eff156157f62075215e795e774803a6f96aYigit Boyar = new GridLayoutManager.SpanSizeLookup() { 25373304eff156157f62075215e795e774803a6f96aYigit Boyar @Override 25473304eff156157f62075215e795e774803a6f96aYigit Boyar public int getSpanSize(int position) { 25573304eff156157f62075215e795e774803a6f96aYigit Boyar if (position > 200) { 25673304eff156157f62075215e795e774803a6f96aYigit Boyar return 100; 25773304eff156157f62075215e795e774803a6f96aYigit Boyar } 25873304eff156157f62075215e795e774803a6f96aYigit Boyar if (position > 20) { 25973304eff156157f62075215e795e774803a6f96aYigit Boyar return 2; 26073304eff156157f62075215e795e774803a6f96aYigit Boyar } 26173304eff156157f62075215e795e774803a6f96aYigit Boyar return 1; 26273304eff156157f62075215e795e774803a6f96aYigit Boyar } 26373304eff156157f62075215e795e774803a6f96aYigit Boyar }; 26473304eff156157f62075215e795e774803a6f96aYigit Boyar glm.setSpanSizeLookup(spanSizeLookup); 26573304eff156157f62075215e795e774803a6f96aYigit Boyar glm.mAnchorInfo.mPosition = 11; 26642c4af4ff383daf001263ae18a9b00b9fbf87487Yigit Boyar RecyclerView.State state = new RecyclerView.State(); 267061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar state.mItemCount = 1000; 2689ace89f49ed497e649b127beb12b8a237e5d30e7Yigit Boyar glm.onAnchorReady(state, glm.mAnchorInfo); 26973304eff156157f62075215e795e774803a6f96aYigit Boyar assertEquals("gm should keep anchor in first span", 11, glm.mAnchorInfo.mPosition); 27073304eff156157f62075215e795e774803a6f96aYigit Boyar 27173304eff156157f62075215e795e774803a6f96aYigit Boyar glm.mAnchorInfo.mPosition = 13; 2729ace89f49ed497e649b127beb12b8a237e5d30e7Yigit Boyar glm.onAnchorReady(state, glm.mAnchorInfo); 27373304eff156157f62075215e795e774803a6f96aYigit Boyar assertEquals("gm should move anchor to first span", 11, glm.mAnchorInfo.mPosition); 27473304eff156157f62075215e795e774803a6f96aYigit Boyar 27573304eff156157f62075215e795e774803a6f96aYigit Boyar glm.mAnchorInfo.mPosition = 23; 2769ace89f49ed497e649b127beb12b8a237e5d30e7Yigit Boyar glm.onAnchorReady(state, glm.mAnchorInfo); 27773304eff156157f62075215e795e774803a6f96aYigit Boyar assertEquals("gm should move anchor to first span", 21, glm.mAnchorInfo.mPosition); 27873304eff156157f62075215e795e774803a6f96aYigit Boyar 27973304eff156157f62075215e795e774803a6f96aYigit Boyar glm.mAnchorInfo.mPosition = 35; 2809ace89f49ed497e649b127beb12b8a237e5d30e7Yigit Boyar glm.onAnchorReady(state, glm.mAnchorInfo); 28173304eff156157f62075215e795e774803a6f96aYigit Boyar assertEquals("gm should move anchor to first span", 31, glm.mAnchorInfo.mPosition); 28273304eff156157f62075215e795e774803a6f96aYigit Boyar } 28373304eff156157f62075215e795e774803a6f96aYigit Boyar 28473304eff156157f62075215e795e774803a6f96aYigit Boyar public void testSpanLookup() { 285061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar spanLookupTest(false); 286061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 287061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 288061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public void testSpanLookupWithCache() { 289061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar spanLookupTest(true); 290061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 291061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 292061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public void testSpanLookupCache() { 293061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar final GridLayoutManager.SpanSizeLookup ssl 294061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar = new GridLayoutManager.SpanSizeLookup() { 295061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar @Override 296061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public int getSpanSize(int position) { 297061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar if (position > 6) { 298061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar return 2; 299061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 300061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar return 1; 301061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 302061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar }; 303061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar ssl.setSpanIndexCacheEnabled(true); 304061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals("reference child non existent", -1, ssl.findReferenceIndexFromCache(2)); 305061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar ssl.getCachedSpanIndex(4, 5); 306061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals("reference child non existent", -1, ssl.findReferenceIndexFromCache(3)); 307061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar // this should not happen and if happens, it is better to return -1 308061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals("reference child itself", -1, ssl.findReferenceIndexFromCache(4)); 309061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals("reference child before", 4, ssl.findReferenceIndexFromCache(5)); 310061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals("reference child before", 4, ssl.findReferenceIndexFromCache(100)); 311061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar ssl.getCachedSpanIndex(6, 5); 312061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals("reference child before", 6, ssl.findReferenceIndexFromCache(7)); 313061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals("reference child before", 4, ssl.findReferenceIndexFromCache(6)); 314061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals("reference child itself", -1, ssl.findReferenceIndexFromCache(4)); 315061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar ssl.getCachedSpanIndex(12, 5); 316061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals("reference child before", 12, ssl.findReferenceIndexFromCache(13)); 317061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals("reference child before", 6, ssl.findReferenceIndexFromCache(12)); 318061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals("reference child before", 6, ssl.findReferenceIndexFromCache(7)); 319061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar for (int i = 0; i < 6; i++) { 320061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar ssl.getCachedSpanIndex(i, 5); 321061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 322061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 323061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar for (int i = 1; i < 7; i++) { 324061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals("reference child right before " + i, i - 1, 325061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar ssl.findReferenceIndexFromCache(i)); 326061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 327061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals("reference child before 0 ", -1, ssl.findReferenceIndexFromCache(0)); 328061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 329061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 330061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public void spanLookupTest(boolean enableCache) { 33173304eff156157f62075215e795e774803a6f96aYigit Boyar final GridLayoutManager.SpanSizeLookup ssl 33273304eff156157f62075215e795e774803a6f96aYigit Boyar = new GridLayoutManager.SpanSizeLookup() { 33373304eff156157f62075215e795e774803a6f96aYigit Boyar @Override 33473304eff156157f62075215e795e774803a6f96aYigit Boyar public int getSpanSize(int position) { 33573304eff156157f62075215e795e774803a6f96aYigit Boyar if (position > 200) { 33673304eff156157f62075215e795e774803a6f96aYigit Boyar return 100; 33773304eff156157f62075215e795e774803a6f96aYigit Boyar } 33873304eff156157f62075215e795e774803a6f96aYigit Boyar if (position > 6) { 33973304eff156157f62075215e795e774803a6f96aYigit Boyar return 2; 34073304eff156157f62075215e795e774803a6f96aYigit Boyar } 34173304eff156157f62075215e795e774803a6f96aYigit Boyar return 1; 34273304eff156157f62075215e795e774803a6f96aYigit Boyar } 34373304eff156157f62075215e795e774803a6f96aYigit Boyar }; 344061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar ssl.setSpanIndexCacheEnabled(enableCache); 345061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals(0, ssl.getCachedSpanIndex(0, 5)); 346061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals(4, ssl.getCachedSpanIndex(4, 5)); 347061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals(0, ssl.getCachedSpanIndex(5, 5)); 348061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals(1, ssl.getCachedSpanIndex(6, 5)); 349061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals(2, ssl.getCachedSpanIndex(7, 5)); 350061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals(2, ssl.getCachedSpanIndex(9, 5)); 351061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals(0, ssl.getCachedSpanIndex(8, 5)); 352061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 353061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 354a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar public void testSpanGroupIndex() { 355a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar final GridLayoutManager.SpanSizeLookup ssl 356a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar = new GridLayoutManager.SpanSizeLookup() { 357a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar @Override 358a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar public int getSpanSize(int position) { 359a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar if (position > 200) { 360a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar return 100; 361a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar } 362a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar if (position > 6) { 363a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar return 2; 364a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar } 365a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar return 1; 366a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar } 367a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar }; 368a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar assertEquals(0, ssl.getSpanGroupIndex(0, 5)); 369a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar assertEquals(0, ssl.getSpanGroupIndex(4, 5)); 370a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar assertEquals(1, ssl.getSpanGroupIndex(5, 5)); 371a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar assertEquals(1, ssl.getSpanGroupIndex(6, 5)); 372a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar assertEquals(1, ssl.getSpanGroupIndex(7, 5)); 373a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar assertEquals(2, ssl.getSpanGroupIndex(9, 5)); 374a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar assertEquals(2, ssl.getSpanGroupIndex(8, 5)); 375a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar } 376a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar 377061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public void testNotifyDataSetChange() throws Throwable { 378061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar final RecyclerView recyclerView = setupBasic(new Config(3, 100)); 379061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar final GridLayoutManager.SpanSizeLookup ssl = mGlm.getSpanSizeLookup(); 380061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar ssl.setSpanIndexCacheEnabled(true); 381061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar waitForFirstLayout(recyclerView); 382061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertTrue("some positions should be cached", ssl.mSpanIndexCache.size() > 0); 383061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar final Callback callback = new Callback() { 384061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar @Override 385061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public void onBeforeLayout(RecyclerView.Recycler recycler, RecyclerView.State state) { 386061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar if (!state.isPreLayout()) { 387061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals("cache should be empty", 0, ssl.mSpanIndexCache.size()); 388061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 389061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 390061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 391061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar @Override 392061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public void onAfterLayout(RecyclerView.Recycler recycler, RecyclerView.State state) { 393061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar if (!state.isPreLayout()) { 394061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertTrue("some items should be cached", ssl.mSpanIndexCache.size() > 0); 395061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 396061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 397061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar }; 398061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mGlm.mCallbacks.add(callback); 399061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mGlm.expectLayout(2); 400061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mAdapter.deleteAndNotify(2, 3); 401061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mGlm.waitForLayout(2); 402061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar checkForMainThreadException(); 403061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 404061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 405afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar public void testUnevenHeights() throws Throwable { 406afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar final Map<Integer, RecyclerView.ViewHolder> viewHolderMap = 407afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar new HashMap<Integer, RecyclerView.ViewHolder>(); 408afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar RecyclerView recyclerView = setupBasic(new Config(3, 3), new GridTestAdapter(3) { 409afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar @Override 410afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar public void onBindViewHolder(TestViewHolder holder, 411afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar int position) { 412afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar super.onBindViewHolder(holder, position); 413afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar final GridLayoutManager.LayoutParams glp = ensureGridLp(holder.itemView); 414afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar glp.height = 50 + position * 50; 415afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar viewHolderMap.put(position, holder); 416afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar } 417afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar }); 418afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar waitForFirstLayout(recyclerView); 419afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar for (RecyclerView.ViewHolder vh : viewHolderMap.values()) { 420afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar assertEquals("all items should get max height", 150, 421afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar vh.itemView.getHeight()); 422afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar } 423afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar 424afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar for (RecyclerView.ViewHolder vh : viewHolderMap.values()) { 425afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar assertEquals("all items should have measured the max height", 150, 426afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar vh.itemView.getMeasuredHeight()); 427afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar } 428afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar } 429afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar 430afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar public void testUnevenWidths() throws Throwable { 431afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar final Map<Integer, RecyclerView.ViewHolder> viewHolderMap = 432afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar new HashMap<Integer, RecyclerView.ViewHolder>(); 433afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar RecyclerView recyclerView = setupBasic(new Config(3, HORIZONTAL, false), 434afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar new GridTestAdapter(3) { 435afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar @Override 436afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar public void onBindViewHolder(TestViewHolder holder, 437afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar int position) { 438afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar super.onBindViewHolder(holder, position); 439afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar final GridLayoutManager.LayoutParams glp = ensureGridLp(holder.itemView); 440afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar glp.width = 50 + position * 50; 441afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar viewHolderMap.put(position, holder); 442afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar } 443afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar }); 444afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar waitForFirstLayout(recyclerView); 445afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar for (RecyclerView.ViewHolder vh : viewHolderMap.values()) { 446afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar assertEquals("all items should get max width", 150, 447afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar vh.itemView.getWidth()); 448afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar } 449afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar 450afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar for (RecyclerView.ViewHolder vh : viewHolderMap.values()) { 451afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar assertEquals("all items should have measured the max width", 150, 452afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar vh.itemView.getMeasuredWidth()); 453afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar } 454afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar } 455afa0494a97687b705feb3659385578f33f697ea9Yigit Boyar 456061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public void testScrollBackAndPreservePositions() throws Throwable { 457061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar for (Config config : mBaseVariations) { 458061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar config.mItemCount = 150; 459061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar scrollBackAndPreservePositionsTest(config); 460061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar removeRecyclerView(); 461061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 462061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 463061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 464061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public void testCacheSpanIndices() throws Throwable { 465061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar final RecyclerView rv = setupBasic(new Config(3, 100)); 466061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mGlm.mSpanSizeLookup.setSpanIndexCacheEnabled(true); 467061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar waitForFirstLayout(rv); 468061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar GridLayoutManager.SpanSizeLookup ssl = mGlm.mSpanSizeLookup; 469061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertTrue("cache should be filled", mGlm.mSpanSizeLookup.mSpanIndexCache.size() > 0); 470061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals("item index 5 should be in span 2", 2, 471061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar getLp(mGlm.findViewByPosition(5)).getSpanIndex()); 472061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mGlm.expectLayout(2); 473061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mAdapter.mFullSpanItems.add(4); 474061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mAdapter.changeAndNotify(4, 1); 475061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mGlm.waitForLayout(2); 476061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals("item index 5 should be in span 2", 0, 477061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar getLp(mGlm.findViewByPosition(5)).getSpanIndex()); 478061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 479061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 480061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar GridLayoutManager.LayoutParams getLp(View view) { 481061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar return (GridLayoutManager.LayoutParams) view.getLayoutParams(); 482061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 483061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 484061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public void scrollBackAndPreservePositionsTest(final Config config) throws Throwable { 485061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar final RecyclerView rv = setupBasic(config); 486061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar for (int i = 1; i < mAdapter.getItemCount(); i += config.mSpanCount + 2) { 487061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mAdapter.setFullSpan(i); 488061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 489061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar waitForFirstLayout(rv); 490061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar final int[] globalPositions = new int[mAdapter.getItemCount()]; 491061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar Arrays.fill(globalPositions, Integer.MIN_VALUE); 492061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar final int scrollStep = (mGlm.mOrientationHelper.getTotalSpace() / 20) 493061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar * (config.mReverseLayout ? -1 : 1); 494061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar final String logPrefix = config.toString(); 495061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar final int[] globalPos = new int[1]; 496061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar runTestOnUiThread(new Runnable() { 497061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar @Override 498061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public void run() { 499061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar int globalScrollPosition = 0; 500061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar int visited = 0; 501061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar while (visited < mAdapter.getItemCount()) { 502061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar for (int i = 0; i < mRecyclerView.getChildCount(); i++) { 503061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar View child = mRecyclerView.getChildAt(i); 504061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar final int pos = mRecyclerView.getChildPosition(child); 505061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar if (globalPositions[pos] != Integer.MIN_VALUE) { 506061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar continue; 507061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 508061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar visited++; 509061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar GridLayoutManager.LayoutParams lp = (GridLayoutManager.LayoutParams) 510061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar child.getLayoutParams(); 511061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar if (config.mReverseLayout) { 512061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar globalPositions[pos] = globalScrollPosition + 513061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mGlm.mOrientationHelper.getDecoratedEnd(child); 514061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } else { 515061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar globalPositions[pos] = globalScrollPosition + 516061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mGlm.mOrientationHelper.getDecoratedStart(child); 517061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 518061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals(logPrefix + " span index should match", 519061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mGlm.getSpanSizeLookup().getSpanIndex(pos, mGlm.getSpanCount()), 520061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar lp.getSpanIndex()); 521061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 522061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar int scrolled = mGlm.scrollBy(scrollStep, 523061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mRecyclerView.mRecycler, mRecyclerView.mState); 524061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar globalScrollPosition += scrolled; 525061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar if (scrolled == 0) { 526061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals( 527061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar logPrefix + " If scroll is complete, all views should be visited", 528061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar visited, mAdapter.getItemCount()); 529061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 530061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 531061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar if (DEBUG) { 532061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar Log.d(TAG, "done recording positions " + Arrays.toString(globalPositions)); 533061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 534061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar globalPos[0] = globalScrollPosition; 535061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 536061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar }); 537061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar checkForMainThreadException(); 538061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar runTestOnUiThread(new Runnable() { 539061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar @Override 540061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public void run() { 541061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar int globalScrollPosition = globalPos[0]; 542061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar // now scroll back and make sure global positions match 543061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar BitSet shouldTest = new BitSet(mAdapter.getItemCount()); 544061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar shouldTest.set(0, mAdapter.getItemCount() - 1, true); 545061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar String assertPrefix = config 546061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar + " global pos must match when scrolling in reverse for position "; 547061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar int scrollAmount = Integer.MAX_VALUE; 548061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar while (!shouldTest.isEmpty() && scrollAmount != 0) { 549061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar for (int i = 0; i < mRecyclerView.getChildCount(); i++) { 550061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar View child = mRecyclerView.getChildAt(i); 551061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar int pos = mRecyclerView.getChildPosition(child); 552061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar if (!shouldTest.get(pos)) { 553061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar continue; 554061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 555061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar GridLayoutManager.LayoutParams lp = (GridLayoutManager.LayoutParams) 556061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar child.getLayoutParams(); 557061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar shouldTest.clear(pos); 558061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar int globalPos; 559061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar if (config.mReverseLayout) { 560061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar globalPos = globalScrollPosition + 561061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mGlm.mOrientationHelper.getDecoratedEnd(child); 562061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } else { 563061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar globalPos = globalScrollPosition + 564061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mGlm.mOrientationHelper.getDecoratedStart(child); 565061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 566061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals(assertPrefix + pos, 567061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar globalPositions[pos], globalPos); 568061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertEquals("span index should match", 569061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mGlm.getSpanSizeLookup().getSpanIndex(pos, mGlm.getSpanCount()), 570061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar lp.getSpanIndex()); 571061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 572061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar scrollAmount = mGlm.scrollBy(-scrollStep, 573061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mRecyclerView.mRecycler, mRecyclerView.mState); 574061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar globalScrollPosition += scrollAmount; 575061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 576061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar assertTrue("all views should be seen", shouldTest.isEmpty()); 577061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 578061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar }); 579061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar checkForMainThreadException(); 580061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 581061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 582061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar class WrappedGridLayoutManager extends GridLayoutManager { 583061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 584061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar CountDownLatch mLayoutLatch; 585061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 586061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar List<Callback> mCallbacks = new ArrayList<Callback>(); 587061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 588061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public WrappedGridLayoutManager(Context context, int spanCount) { 589061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar super(context, spanCount); 590061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 591061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 592061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public WrappedGridLayoutManager(Context context, int spanCount, int orientation, 593061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar boolean reverseLayout) { 594061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar super(context, spanCount, orientation, reverseLayout); 595061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 596061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 597061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar @Override 598061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) { 599061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar try { 600061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar for (Callback callback : mCallbacks) { 601061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar callback.onBeforeLayout(recycler, state); 602061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 603061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar super.onLayoutChildren(recycler, state); 604061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar for (Callback callback : mCallbacks) { 605061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar callback.onAfterLayout(recycler, state); 606061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 607061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } catch (Throwable t) { 608061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar postExceptionToInstrumentation(t); 609061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 610061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mLayoutLatch.countDown(); 611061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 612061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 613061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public void expectLayout(int layoutCount) { 614061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mLayoutLatch = new CountDownLatch(layoutCount); 615061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 616061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 617061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public void waitForLayout(int seconds) throws InterruptedException { 618061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mLayoutLatch.await(seconds, SECONDS); 619061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 620061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 621061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 622061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar class Config { 623061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 624061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar int mSpanCount; 625061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar int mOrientation = GridLayoutManager.VERTICAL; 626061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar int mItemCount = 1000; 627061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar boolean mReverseLayout = false; 628061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 629061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar Config(int spanCount, int itemCount) { 630061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mSpanCount = spanCount; 631061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mItemCount = itemCount; 632061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 633061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 634061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public Config(int spanCount, int orientation, boolean reverseLayout) { 635061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mSpanCount = spanCount; 636061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mOrientation = orientation; 637061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mReverseLayout = reverseLayout; 638061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 639061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 640061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar Config orientation(int orientation) { 641061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mOrientation = orientation; 642061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar return this; 643061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 644061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 645061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar @Override 646061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public String toString() { 647061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar return "Config{" + 648061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar "mSpanCount=" + mSpanCount + 649061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar ", mOrientation=" + (mOrientation == GridLayoutManager.HORIZONTAL ? "h" : "v") + 650061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar ", mItemCount=" + mItemCount + 651061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar ", mReverseLayout=" + mReverseLayout + 652061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar '}'; 653061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 654061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 655061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 656061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar class GridTestAdapter extends TestAdapter { 657061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 658061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar Set<Integer> mFullSpanItems = new HashSet<Integer>(); 659061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 660061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar GridTestAdapter(int count) { 661061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar super(count); 662061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 663061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 664061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar void setFullSpan(int... items) { 665061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar for (int i : items) { 666061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar mFullSpanItems.add(i); 667061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 668061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 669061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 670061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar void assignSpanSizeLookup(final GridLayoutManager glm) { 671061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar glm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { 672061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar @Override 673061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public int getSpanSize(int position) { 674061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar return mFullSpanItems.contains(position) ? glm.getSpanCount() : 1; 675061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 676061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar }); 677061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 678061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 679061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 680061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar class Callback { 681061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 682061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public void onBeforeLayout(RecyclerView.Recycler recycler, RecyclerView.State state) { 683061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 684061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar 685061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar public void onAfterLayout(RecyclerView.Recycler recycler, RecyclerView.State state) { 686061c3284cf284424ae084799dd7ba5c8d6d59faaYigit Boyar } 68773304eff156157f62075215e795e774803a6f96aYigit Boyar } 68873304eff156157f62075215e795e774803a6f96aYigit Boyar} 689