[go: nahoru, domu]

14143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar/*
24143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * Copyright (C) 2014 The Android Open Source Project
34143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar *
44143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
54143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * you may not use this file except in compliance with the License.
64143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * You may obtain a copy of the License at
74143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar *
84143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
94143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar *
104143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * Unless required by applicable law or agreed to in writing, software
114143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
124143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * See the License for the specific language governing permissions and
144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * limitations under the License.
154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar */
164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarpackage android.support.v7.widget;
184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
194143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport org.junit.Test;
204143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport org.junit.runner.RunWith;
214143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport org.junit.runners.Parameterized;
22f7f1c1ef2a0e0696fbfa8065ac88cd1f8dd39623Yigit Boyar
234143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.util.Log;
244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.view.View;
254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport java.util.Arrays;
274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport java.util.BitSet;
284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport java.util.List;
294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport static org.junit.Assert.assertEquals;
314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport static org.junit.Assert.assertSame;
324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport static org.junit.Assert.assertTrue;
334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar@RunWith(Parameterized.class)
354143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarpublic class GridLayoutManagerBaseConfigSetTest extends BaseGridLayoutManagerTest {
364143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    @Parameterized.Parameters(name = "{0}")
374143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    public static List<Config> params() {
384143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        return createBaseVariations();
394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    private final Config mConfig;
424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    public GridLayoutManagerBaseConfigSetTest(Config config) {
444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        mConfig = config;
454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    @Test
484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    public void scrollBackAndPreservePositions() throws Throwable {
494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        Config config = (Config) mConfig.clone();
504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        config.mItemCount = 150;
514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        scrollBackAndPreservePositionsTest(config);
524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
534143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    public void scrollBackAndPreservePositionsTest(final Config config) throws Throwable {
554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        final RecyclerView rv = setupBasic(config);
564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        for (int i = 1; i < mAdapter.getItemCount(); i += config.mSpanCount + 2) {
574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            mAdapter.setFullSpan(i);
584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        waitForFirstLayout(rv);
604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        final int[] globalPositions = new int[mAdapter.getItemCount()];
614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        Arrays.fill(globalPositions, Integer.MIN_VALUE);
624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        final int scrollStep = (mGlm.mOrientationHelper.getTotalSpace() / 20)
634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                * (config.mReverseLayout ? -1 : 1);
644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        final String logPrefix = config.toString();
654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        final int[] globalPos = new int[1];
664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        runTestOnUiThread(new Runnable() {
674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            @Override
684143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            public void run() {
694143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                assertSame("test sanity", mRecyclerView, rv);
704143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                int globalScrollPosition = 0;
714143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                int visited = 0;
724143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                while (visited < mAdapter.getItemCount()) {
734143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    for (int i = 0; i < mRecyclerView.getChildCount(); i++) {
744143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        View child = mRecyclerView.getChildAt(i);
754143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        final int pos = mRecyclerView.getChildLayoutPosition(child);
764143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        if (globalPositions[pos] != Integer.MIN_VALUE) {
774143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                            continue;
784143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        }
794143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        visited++;
804143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        GridLayoutManager.LayoutParams lp = (GridLayoutManager.LayoutParams)
814143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                                child.getLayoutParams();
824143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        if (config.mReverseLayout) {
834143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                            globalPositions[pos] = globalScrollPosition +
844143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                                    mGlm.mOrientationHelper.getDecoratedEnd(child);
854143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        } else {
864143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                            globalPositions[pos] = globalScrollPosition +
874143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                                    mGlm.mOrientationHelper.getDecoratedStart(child);
884143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        }
894143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        assertEquals(logPrefix + " span index should match",
904143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                                mGlm.getSpanSizeLookup().getSpanIndex(pos, mGlm.getSpanCount()),
914143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                                lp.getSpanIndex());
924143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    }
934143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    int scrolled = mGlm.scrollBy(scrollStep,
944143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                            mRecyclerView.mRecycler, mRecyclerView.mState);
954143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    globalScrollPosition += scrolled;
964143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    if (scrolled == 0) {
974143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        assertEquals(
984143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                                logPrefix + " If scroll is complete, all views should be visited",
994143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                                visited, mAdapter.getItemCount());
1004143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    }
1014143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                }
1024143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                if (DEBUG) {
1034143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    Log.d(TAG, "done recording positions " + Arrays.toString(globalPositions));
1044143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                }
1054143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                globalPos[0] = globalScrollPosition;
1064143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
1074143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        });
1084143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        checkForMainThreadException();
1094143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        // test sanity, ensure scroll happened
1104143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        runTestOnUiThread(new Runnable() {
1114143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            @Override
1124143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            public void run() {
1134143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                final int childCount = mGlm.getChildCount();
1144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                final BitSet expectedPositions = new BitSet();
1154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                for (int i = 0; i < childCount; i ++) {
1164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    expectedPositions.set(mAdapter.getItemCount() - i - 1);
1174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                }
1184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                for (int i = 0; i <childCount; i ++) {
1194143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    final View view = mGlm.getChildAt(i);
1204143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    int position = mGlm.getPosition(view);
1214143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    assertTrue("child position should be in last page", expectedPositions.get(position));
1224143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                }
1234143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
1244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        });
1254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        getInstrumentation().waitForIdleSync();
1264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        runTestOnUiThread(new Runnable() {
1274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            @Override
1284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            public void run() {
1294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                int globalScrollPosition = globalPos[0];
1304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                // now scroll back and make sure global positions match
1314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                BitSet shouldTest = new BitSet(mAdapter.getItemCount());
1324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                shouldTest.set(0, mAdapter.getItemCount() - 1, true);
1334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                String assertPrefix = config
1344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        + " global pos must match when scrolling in reverse for position ";
1354143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                int scrollAmount = Integer.MAX_VALUE;
1364143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                while (!shouldTest.isEmpty() && scrollAmount != 0) {
1374143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    for (int i = 0; i < mRecyclerView.getChildCount(); i++) {
1384143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        View child = mRecyclerView.getChildAt(i);
1394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        int pos = mRecyclerView.getChildLayoutPosition(child);
1404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        if (!shouldTest.get(pos)) {
1414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                            continue;
1424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        }
1434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        GridLayoutManager.LayoutParams lp = (GridLayoutManager.LayoutParams)
1444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                                child.getLayoutParams();
1454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        shouldTest.clear(pos);
1464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        int globalPos;
1474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        if (config.mReverseLayout) {
1484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                            globalPos = globalScrollPosition +
1494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                                    mGlm.mOrientationHelper.getDecoratedEnd(child);
1504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        } else {
1514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                            globalPos = globalScrollPosition +
1524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                                    mGlm.mOrientationHelper.getDecoratedStart(child);
1534143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        }
1544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        assertEquals(assertPrefix + pos,
1554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                                globalPositions[pos], globalPos);
1564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        assertEquals("span index should match",
1574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                                mGlm.getSpanSizeLookup().getSpanIndex(pos, mGlm.getSpanCount()),
1584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                                lp.getSpanIndex());
1594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    }
1604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    scrollAmount = mGlm.scrollBy(-scrollStep,
1614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                            mRecyclerView.mRecycler, mRecyclerView.mState);
1624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    globalScrollPosition += scrollAmount;
1634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                }
1644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                assertTrue("all views should be seen", shouldTest.isEmpty());
1654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
1664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        });
1674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        checkForMainThreadException();
1684143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
1694143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar}
170