GridWidgetTest.java revision d1cab1b54104d55407335c5d649398635822fffd
1062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu/*
2062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * Copyright (C) 2015 The Android Open Source Project
3062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu *
4062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * Licensed under the Apache License, Version 2.0 (the "License");
5062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * you may not use this file except in compliance with the License.
6062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * You may obtain a copy of the License at
7062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu *
8062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu *      http://www.apache.org/licenses/LICENSE-2.0
9062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu *
10062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * Unless required by applicable law or agreed to in writing, software
11062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * distributed under the License is distributed on an "AS IS" BASIS,
12062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * See the License for the specific language governing permissions and
14062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * limitations under the License.
15062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu */
16062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gupackage android.support.v17.leanback.widget;
17062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
18247741d74797105ba4f6d2834ec56dab32c14644Dake Guimport android.support.v17.leanback.tests.R;
19062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.test.ActivityInstrumentationTestCase2;
203bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Guimport android.text.Selection;
213bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Guimport android.text.Spannable;
22062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.util.Log;
233bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Guimport android.util.SparseArray;
24062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.view.KeyEvent;
25062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.view.View;
26062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.view.ViewGroup;
27c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Guimport android.widget.TextView;
28d1cab1b54104d55407335c5d649398635822fffdDake Gu
29d1cab1b54104d55407335c5d649398635822fffdDake Guimport android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
30d1cab1b54104d55407335c5d649398635822fffdDake Guimport android.support.v7.widget.RecyclerViewAccessibilityDelegate;
31d1cab1b54104d55407335c5d649398635822fffdDake Gu
32062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.app.Instrumentation;
33062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.content.Intent;
343bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Guimport android.os.Parcelable;
35062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
36062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport java.util.ArrayList;
37062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport java.util.Arrays;
38062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport java.util.Comparator;
39062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport java.util.HashMap;
40062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport java.util.Iterator;
41062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
42062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu/**
43062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * @hide from javadoc
44062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu */
45062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gupublic class GridWidgetTest extends ActivityInstrumentationTestCase2<GridActivity> {
46062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
47f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    private static final boolean HUMAN_DELAY = false;
487538845719cd1e588185ce9ae60320377862ef8dDake Gu    private static final long WAIT_FOR_SCROLL_IDLE_TIMEOUT_MS = 60000;
49f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu
50062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    protected GridActivity mActivity;
51062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    protected Instrumentation mInstrumentation;
52062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    protected BaseGridView mGridView;
5385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    protected GridLayoutManager mLayoutManager;
54062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    protected int mOrientation;
55247741d74797105ba4f6d2834ec56dab32c14644Dake Gu    protected int mNumRows;
56062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
57062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    private final Comparator<View> mRowSortComparator = new Comparator<View>() {
58062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        public int compare(View lhs, View rhs) {
59062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            if (mOrientation == BaseGridView.HORIZONTAL) {
60062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu                return lhs.getLeft() - rhs.getLeft();
61062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            } else {
62062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu                return lhs.getTop() - rhs.getTop();
63062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            }
64062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        };
65062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    };
66062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
67062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    /**
68062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu     * Verify margins between items on same row are same.
69062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu     */
70062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    private final Runnable mVerifyLayout = new Runnable() {
71062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        @Override
72062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        public void run() {
73e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            verifyMargin();
74062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        }
75062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    };
76062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
77062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    public GridWidgetTest() {
78062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        super("android.support.v17.leanback.tests", GridActivity.class);
79062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    }
80062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
81f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    private void humanDelay(int delay) throws InterruptedException {
82f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        if (HUMAN_DELAY) Thread.sleep(delay);
83f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    }
84f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    /**
85f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu     * Change size of the Adapter and notifyDataSetChanged.
86f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu     */
87f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    private void changeArraySize(final int size) throws Throwable {
88f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        runTestOnUiThread(new Runnable() {
89f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu            public void run() {
90f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu                mActivity.changeArraySize(size);
91f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu            }
92f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        });
93f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        Thread.sleep(500);
94f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    }
95f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu
96f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    /**
97f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu     * Change selected position.
98f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu     */
99f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    private void setSelectedPosition(final int position, final int scrollExtra) throws Throwable {
100f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        runTestOnUiThread(new Runnable() {
101f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu            public void run() {
102f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu                mGridView.setSelectedPosition(position, scrollExtra);
103f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu            }
104f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        });
105f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        Thread.sleep(500);
106f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    }
107f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu
108062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    /**
109062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu     * Wait for grid view stop scroll and optionally verify state of grid view.
110062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu     */
111062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    protected void waitForScrollIdle(Runnable verify) throws Throwable {
1128c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Thread.sleep(100);
1137538845719cd1e588185ce9ae60320377862ef8dDake Gu        int total = 0;
114062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        while (mGridView.getLayoutManager().isSmoothScrolling() ||
115062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu                mGridView.getScrollState() != BaseGridView.SCROLL_STATE_IDLE) {
1167538845719cd1e588185ce9ae60320377862ef8dDake Gu            if ((total += 100) >= WAIT_FOR_SCROLL_IDLE_TIMEOUT_MS) {
1177538845719cd1e588185ce9ae60320377862ef8dDake Gu                throw new RuntimeException("waitForScrollIdle Timeout");
1187538845719cd1e588185ce9ae60320377862ef8dDake Gu            }
119062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            try {
120062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu                Thread.sleep(100);
121062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            } catch (InterruptedException ex) {
122062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu                break;
123062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            }
124062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            if (verify != null) {
125062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu                runTestOnUiThread(verify);
126062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            }
127062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        }
128062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    }
129062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
130062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    /**
13185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu     * Wait for grid view stop animation and optionally verify state of grid view.
13285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu     */
13385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    protected void waitForTransientStateGone(Runnable verify) throws Throwable {
13485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        do {
13585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            try {
13685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                Thread.sleep(100);
13785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            } catch (InterruptedException ex) {
13885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                break;
13985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            }
14085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            if (verify != null) {
14185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                runTestOnUiThread(verify);
14285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            }
14385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        } while (mGridView.hasTransientState());
14485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    }
14585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
14685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    /**
147062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu     * Wait for grid view stop scroll.
148062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu     */
149062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    protected void waitForScrollIdle() throws Throwable {
150062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        waitForScrollIdle(null);
151062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    }
152062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
153e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    /**
154a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu     * Scrolls using given key.
155a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu     */
156a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu    protected void scroll(int key, Runnable verify) throws Throwable {
157a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        do {
158a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            if (verify != null) {
159a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu                runTestOnUiThread(verify);
160a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            }
161a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            sendRepeatedKeys(10, key);
162a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            try {
1638c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                Thread.sleep(300);
164a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            } catch (InterruptedException ex) {
165a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu                break;
166a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            }
167a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        } while (mGridView.getLayoutManager().isSmoothScrolling() ||
168a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu                mGridView.getScrollState() != BaseGridView.SCROLL_STATE_IDLE);
169a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu    }
170a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu
171a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu    protected void scrollToBegin(Runnable verify) throws Throwable {
172a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        int key;
173a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        if (mOrientation == BaseGridView.HORIZONTAL) {
174a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            if (mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL) {
175a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu                key = KeyEvent.KEYCODE_DPAD_RIGHT;
176a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            } else {
177a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu                key = KeyEvent.KEYCODE_DPAD_LEFT;
178a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            }
179a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        } else {
180a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            key = KeyEvent.KEYCODE_DPAD_UP;
181a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        }
182a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scroll(key, verify);
183a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu    }
184a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu
185a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu    protected void scrollToEnd(Runnable verify) throws Throwable {
186a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        int key;
187a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        if (mOrientation == BaseGridView.HORIZONTAL) {
188a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            if (mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL) {
189a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu                key = KeyEvent.KEYCODE_DPAD_LEFT;
190a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            } else {
191a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu                key = KeyEvent.KEYCODE_DPAD_RIGHT;
192a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            }
193a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        } else {
194a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            key = KeyEvent.KEYCODE_DPAD_DOWN;
195a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        }
196a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scroll(key, verify);
197a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu    }
198a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu
199a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu    /**
200e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu     * Group and sort children by their position on each row (HORIZONTAL) or column(VERTICAL).
201e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu     */
202e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    protected View[][] sortByRows() {
203e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        final HashMap<Integer, ArrayList<View>> rows = new HashMap<Integer, ArrayList<View>>();
204c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        ArrayList<Integer> rowLocations = new ArrayList();
205e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        for (int i = 0; i < mGridView.getChildCount(); i++) {
206e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            View v = mGridView.getChildAt(i);
207e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            int rowLocation;
208e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            if (mOrientation == BaseGridView.HORIZONTAL) {
209e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                rowLocation = v.getTop();
210e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            } else {
211e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                rowLocation = mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL ?
212e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    v.getRight() : v.getLeft();
213e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            }
214e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            ArrayList<View> views = rows.get(rowLocation);
215e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            if (views == null) {
216e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                views = new ArrayList<View>();
217e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                rows.put(rowLocation, views);
218c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                rowLocations.add(rowLocation);
219e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            }
220e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            views.add(v);
221e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        }
222c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        Object[] sortedLocations = rowLocations.toArray();
223c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        Arrays.sort(sortedLocations);
224c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        if (mNumRows != rows.size()) {
225c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            assertEquals("Dump Views by rows "+rows, mNumRows, rows.size());
226c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        }
227e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        View[][] sorted = new View[rows.size()][];
228c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        for (int i = 0; i < rowLocations.size(); i++) {
229c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            Integer rowLocation = rowLocations.get(i);
230c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            ArrayList<View> arr = rows.get(rowLocation);
231e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            View[] views = arr.toArray(new View[arr.size()]);
232e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            Arrays.sort(views, mRowSortComparator);
233c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            sorted[i] = views;
234e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        }
235e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        return sorted;
236e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    }
237e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
238e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    protected void verifyMargin() {
239e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        View[][] sorted = sortByRows();
240e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        for (int row = 0; row < sorted.length; row++) {
241e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            View[] views = sorted[row];
242e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            int margin = -1;
243e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            for (int i = 1; i < views.length; i++) {
244e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                if (mOrientation == BaseGridView.HORIZONTAL) {
245492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                    assertEquals(mGridView.getHorizontalMargin(),
246492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                            views[i].getLeft() - views[i - 1].getRight());
247e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                } else {
248492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                    assertEquals(mGridView.getVerticalMargin(),
249492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                            views[i].getTop() - views[i - 1].getBottom());
250e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                }
251e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            }
252e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        }
253e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    }
254e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
255e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    protected void verifyBeginAligned() {
256e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        View[][] sorted = sortByRows();
257e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        int alignedLocation = 0;
258e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        if (mOrientation == BaseGridView.HORIZONTAL) {
259e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            if (mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL) {
260e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                for (int i = 0; i < sorted.length; i++) {
261e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    if (i == 0) {
262e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                        alignedLocation = sorted[i][sorted[i].length - 1].getRight();
263e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    } else {
264e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                        assertEquals(alignedLocation, sorted[i][sorted[i].length - 1].getRight());
265e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    }
266e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                }
267e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            } else {
268e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                for (int i = 0; i < sorted.length; i++) {
269e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    if (i == 0) {
270e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                        alignedLocation = sorted[i][0].getLeft();
271e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    } else {
272e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                        assertEquals(alignedLocation, sorted[i][0].getLeft());
273e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    }
274e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                }
275e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            }
276e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        } else {
277e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            for (int i = 0; i < sorted.length; i++) {
278e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                if (i == 0) {
279e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    alignedLocation = sorted[i][0].getTop();
280e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                } else {
281e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    assertEquals(alignedLocation, sorted[i][0].getTop());
282e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                }
283e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            }
284e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        }
285e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    }
286e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
287c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu    protected int[] getEndEdges() {
288c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        View[][] sorted = sortByRows();
289c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        int[] edges = new int[sorted.length];
290c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        if (mOrientation == BaseGridView.HORIZONTAL) {
291c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            if (mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL) {
292c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                for (int i = 0; i < sorted.length; i++) {
293c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                    edges[i] = sorted[i][0].getLeft();
294c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                }
295c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            } else {
296c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                for (int i = 0; i < sorted.length; i++) {
297c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                    edges[i] = sorted[i][sorted[i].length - 1].getRight();
298c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                }
299c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            }
300c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        } else {
301c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            for (int i = 0; i < sorted.length; i++) {
302c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                edges[i] = sorted[i][sorted[i].length - 1].getBottom();
303c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            }
304c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        }
305c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        return edges;
306c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu    }
307c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
308c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu    protected void verifyEdgesSame(int[] edges, int[] edges2) {
309c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        assertEquals(edges.length, edges2.length);
310c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        for (int i = 0; i < edges.length; i++) {
311c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            assertEquals(edges[i], edges2[i]);
312c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        }
313c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu    }
314c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
31585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    protected void verifyBoundCount(int count) {
31685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        if (mActivity.getBoundCount() != count) {
31785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            StringBuffer b = new StringBuffer();
31885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            b.append("ItemsLength: ");
31985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            for (int i = 0; i < mActivity.mItemLengths.length; i++) {
32085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                b.append(mActivity.mItemLengths[i]).append(",");
32185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            }
32285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            assertEquals("Bound count does not match, ItemsLengths: "+ b,
32385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                    count, mActivity.getBoundCount());
32485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        }
32585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    }
32685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
3278c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    private static int getCenterY(View v) {
3288c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        return (v.getTop() + v.getBottom())/2;
3298c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    }
330062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
3318c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    private static int getCenterX(View v) {
3328c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        return (v.getLeft() + v.getRight())/2;
3338c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    }
3348c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
3358c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    private void initActivity(Intent intent) {
3368c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        setActivityIntent(intent);
3378c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mActivity = getActivity();
3388c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final String testName = getName();
3398c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        try {
3408c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            runTestOnUiThread(new Runnable() {
3418c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                public void run() {
3428c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                    mActivity.setTitle(testName);
3438c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                }
3448c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            });
3458c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            Thread.sleep(1000);
3468c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        } catch (Throwable t) {
3478c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            t.printStackTrace();
3488c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        }
3498c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mGridView = mActivity.mGridView;
3508c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    }
3518c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
3528c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    public void testThreeRowHorizontalBasic() throws Throwable {
353062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        mInstrumentation = getInstrumentation();
354062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
355247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.horizontal_grid);
356e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 100);
3578c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
358247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
359247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mNumRows = 3;
360062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
361a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
36285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBoundCount(100);
363e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
364a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToBegin(mVerifyLayout);
365062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
366e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        verifyBeginAligned();
367062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    }
368062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
369e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    public void testThreeColumnVerticalBasic() throws Throwable {
370e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
371e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        mInstrumentation = getInstrumentation();
372e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
373247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.vertical_grid);
374e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 200);
3758c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
376247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mOrientation = BaseGridView.VERTICAL;
377247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mNumRows = 3;
378e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
379a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
38085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBoundCount(200);
381e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
382a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToBegin(mVerifyLayout);
38385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
38485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBeginAligned();
38585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    }
38685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
38785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    public void testRedundantAppendRemove() throws Throwable {
38885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mInstrumentation = getInstrumentation();
38985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
390247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
391247741d74797105ba4f6d2834ec56dab32c14644Dake Gu                R.layout.vertical_grid_testredundantappendremove);
39285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, new int[]{
39385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                149,177,128,234,227,187,163,223,146,210,228,148,227,193,182,197,177,142,225,207,
39485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                157,171,209,204,187,184,123,221,197,153,202,179,193,214,226,173,225,143,188,159,
39585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                139,193,233,143,227,203,222,124,228,223,164,131,228,126,211,160,165,152,235,184,
39685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                155,224,149,181,171,229,200,234,177,130,164,172,188,139,132,203,179,220,147,131,
39785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                226,127,230,239,183,203,206,227,123,170,239,234,200,149,237,204,160,133,202,234,
39885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                173,122,139,149,151,153,216,231,121,145,227,153,186,174,223,180,123,215,206,216,
39985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                239,222,219,207,193,218,140,133,171,153,183,132,233,138,159,174,189,171,143,128,
40085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                152,222,141,202,224,190,134,120,181,231,230,136,132,224,136,210,207,150,128,183,
40185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                221,194,179,220,126,221,137,205,223,193,172,132,226,209,133,191,227,127,159,171,
40285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                180,149,237,177,194,207,170,202,161,144,147,199,205,186,164,140,193,203,224,129});
4038c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
404247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mOrientation = BaseGridView.VERTICAL;
405247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mNumRows = 3;
40685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
407a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
40885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
40985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBoundCount(200);
410e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
411a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToBegin(mVerifyLayout);
412e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
413e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        verifyBeginAligned();
414e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    }
41585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
41685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    public void testRedundantAppendRemove2() throws Throwable {
41785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mInstrumentation = getInstrumentation();
41885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
419247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
420247741d74797105ba4f6d2834ec56dab32c14644Dake Gu                R.layout.horizontal_grid_testredundantappendremove2);
42185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, new int[]{
42285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                318,333,199,224,246,273,269,289,340,313,265,306,349,269,185,282,257,354,316,252,
42385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                237,290,283,343,196,313,290,343,191,262,342,228,343,349,251,203,226,305,265,213,
42485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                216,333,295,188,187,281,288,311,244,232,224,332,290,181,267,276,226,261,335,355,
42585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                225,217,219,183,234,285,257,304,182,250,244,223,257,219,342,185,347,205,302,315,
42685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                299,309,292,237,192,309,228,250,347,227,337,298,299,185,185,331,223,284,265,351});
4278c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
428247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
429247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mNumRows = 3;
43085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mLayoutManager = (GridLayoutManager) mGridView.getLayoutManager();
43185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
43285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        // test append without staggered result cache
433a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
43485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
43585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBoundCount(100);
436c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        int[] endEdges = getEndEdges();
43785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
438a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToBegin(mVerifyLayout);
43985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
44085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBeginAligned();
44185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
44285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        // now test append with staggered result cache
443f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(3);
44485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        assertEquals("Staggerd cache should be kept as is when no item size change",
44585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                100, ((StaggeredGrid) mLayoutManager.mGrid).mLocations.size());
44685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
44785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mActivity.resetBoundCount();
448f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(100);
44985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
450a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
45185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBoundCount(100);
452c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
453c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        // we should get same aligned end edges
454c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        int[] endEdges2 = getEndEdges();
455c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        verifyEdgesSame(endEdges, endEdges2);
45685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    }
45785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
458c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu    public void testItemMovedHorizontal() throws Throwable {
45985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
46085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mInstrumentation = getInstrumentation();
46185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
462247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
463247741d74797105ba4f6d2834ec56dab32c14644Dake Gu                R.layout.horizontal_grid);
46485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 200);
4658c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
466247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
467247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mNumRows = 3;
46885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
46985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mGridView.setSelectedPositionSmooth(150);
47085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        waitForScrollIdle(mVerifyLayout);
47185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mActivity.swap(150, 152);
47285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        waitForTransientStateGone(null);
47385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
47485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        runTestOnUiThread(mVerifyLayout);
47585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
476a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToBegin(mVerifyLayout);
47785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
47885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBeginAligned();
47985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    }
48085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
481c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu    public void testItemMovedVertical() throws Throwable {
482c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
483c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        mInstrumentation = getInstrumentation();
484c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
485c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
486c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                R.layout.vertical_grid);
487c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 200);
4888c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
489c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        mOrientation = BaseGridView.VERTICAL;
490c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        mNumRows = 3;
491c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
492c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        mGridView.setSelectedPositionSmooth(150);
493c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        waitForScrollIdle(mVerifyLayout);
494c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        mActivity.swap(150, 152);
495c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        waitForTransientStateGone(null);
496c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
497c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        runTestOnUiThread(mVerifyLayout);
498c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
4997ee22537e201c3d6b5de2908aecc4b0cc59a05c2Dake Gu        scrollToEnd(mVerifyLayout);
500a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToBegin(mVerifyLayout);
501c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
502c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        verifyBeginAligned();
503c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu    }
504c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
505ede7fd3c91008fb042c736240534d0d87234f112Dake Gu    public void testItemAddRemoveHorizontal() throws Throwable {
506ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
507ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        mInstrumentation = getInstrumentation();
508ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
509ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
510ede7fd3c91008fb042c736240534d0d87234f112Dake Gu                R.layout.horizontal_grid);
511ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 200);
5128c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
513ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
514ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        mNumRows = 3;
515ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
516a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
517ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        int[] endEdges = getEndEdges();
518ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
519ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        mGridView.setSelectedPositionSmooth(150);
520ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        waitForScrollIdle(mVerifyLayout);
521ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        int[] removedItems = mActivity.removeItems(151, 4);
522ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        waitForTransientStateGone(null);
523ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
524a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
525ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        mGridView.setSelectedPositionSmooth(150);
526ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        waitForScrollIdle(mVerifyLayout);
527ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
528ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        mActivity.addItems(151, removedItems);
529ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        waitForTransientStateGone(null);
530a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
531ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
532ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        // we should get same aligned end edges
533ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        int[] endEdges2 = getEndEdges();
534ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        verifyEdgesSame(endEdges, endEdges2);
535ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
536a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToBegin(mVerifyLayout);
537ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        verifyBeginAligned();
538ede7fd3c91008fb042c736240534d0d87234f112Dake Gu    }
539ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
5409c56475370d1df940252ff1360b92de50022fff6Dake Gu    public void testFocusToFirstItem() throws Throwable {
5419c56475370d1df940252ff1360b92de50022fff6Dake Gu
5429c56475370d1df940252ff1360b92de50022fff6Dake Gu        mInstrumentation = getInstrumentation();
5439c56475370d1df940252ff1360b92de50022fff6Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
5449c56475370d1df940252ff1360b92de50022fff6Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
5459c56475370d1df940252ff1360b92de50022fff6Dake Gu                R.layout.horizontal_grid);
5469c56475370d1df940252ff1360b92de50022fff6Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 200);
5479c56475370d1df940252ff1360b92de50022fff6Dake Gu        initActivity(intent);
5489c56475370d1df940252ff1360b92de50022fff6Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
5499c56475370d1df940252ff1360b92de50022fff6Dake Gu        mNumRows = 3;
5509c56475370d1df940252ff1360b92de50022fff6Dake Gu
5519c56475370d1df940252ff1360b92de50022fff6Dake Gu        int[] removedItems = mActivity.removeItems(0, 200);
5529c56475370d1df940252ff1360b92de50022fff6Dake Gu
5539c56475370d1df940252ff1360b92de50022fff6Dake Gu        waitForTransientStateGone(null);
554f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
5559c56475370d1df940252ff1360b92de50022fff6Dake Gu        mActivity.addItems(0, removedItems);
5569c56475370d1df940252ff1360b92de50022fff6Dake Gu
5579c56475370d1df940252ff1360b92de50022fff6Dake Gu        waitForTransientStateGone(null);
558f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
5599c56475370d1df940252ff1360b92de50022fff6Dake Gu        assertTrue(mGridView.getLayoutManager().findViewByPosition(0).hasFocus());
5609c56475370d1df940252ff1360b92de50022fff6Dake Gu
561f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(0);
5629c56475370d1df940252ff1360b92de50022fff6Dake Gu
563f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(200);
5649c56475370d1df940252ff1360b92de50022fff6Dake Gu        assertTrue(mGridView.getLayoutManager().findViewByPosition(0).hasFocus());
5659c56475370d1df940252ff1360b92de50022fff6Dake Gu    }
5669c56475370d1df940252ff1360b92de50022fff6Dake Gu
56777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu    public void testNonFocusableHorizontal() throws Throwable {
56877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int numItems = 200;
56977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int startPos = 45;
57077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int skips = 20;
57177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int numColumns = 3;
57277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int endPos = startPos + numColumns * (skips + 1);
57377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
57477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mInstrumentation = getInstrumentation();
57577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
57677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
57777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu                R.layout.horizontal_grid);
57877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, numItems);
57977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
58077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mOrientation = BaseGridView.HORIZONTAL;
58177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mNumRows = numColumns;
58277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        boolean[] focusable = new boolean[numItems];
58377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        for (int i = 0; i < focusable.length; i++) {
58477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            focusable[i] = true;
58577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
58677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        for (int i = startPos + mNumRows, j = 0; j < skips; i += mNumRows, j++) {
58777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            focusable[i] = false;
58877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
58977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS_FOCUSABLE, focusable);
5908c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
59177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
59277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mGridView.setSelectedPositionSmooth(startPos);
59377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
59477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
59577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        if (mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL) {
59677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
59777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        } else {
59877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
59977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
60077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
60177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        assertEquals(endPos, mGridView.getSelectedPosition());
60277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
60377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        if (mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL) {
60477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
60577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        } else {
60677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
60777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
60877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
60977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        assertEquals(startPos, mGridView.getSelectedPosition());
61077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
61177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu    }
61277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
61377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
61477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu    public void testNonFocusableVertical() throws Throwable {
61577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int numItems = 200;
61677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int startPos = 44;
61777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int skips = 20;
61877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int numColumns = 3;
61977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int endPos = startPos + numColumns * (skips + 1);
62077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
62177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mInstrumentation = getInstrumentation();
62277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
62377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
62477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu                R.layout.vertical_grid);
62577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, numItems);
62677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
62777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mOrientation = BaseGridView.VERTICAL;
62877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mNumRows = numColumns;
62977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        boolean[] focusable = new boolean[numItems];
63077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        for (int i = 0; i < focusable.length; i++) {
63177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            focusable[i] = true;
63277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
63377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        for (int i = startPos + mNumRows, j = 0; j < skips; i += mNumRows, j++) {
63477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            focusable[i] = false;
63577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
63677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS_FOCUSABLE, focusable);
6378c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
63877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
63977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mGridView.setSelectedPositionSmooth(startPos);
64077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
64177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
64277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
64377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
64477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        assertEquals(endPos, mGridView.getSelectedPosition());
64577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
64677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
64777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
64877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        assertEquals(startPos, mGridView.getSelectedPosition());
64977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
65077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu    }
6516b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
6526b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu    public void testTransferFocusable() throws Throwable {
6536b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int numItems = 200;
6546b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int numColumns = 3;
6556b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int startPos = 1;
6566b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
6576b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mInstrumentation = getInstrumentation();
6586b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
6596b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
6606b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu                R.layout.horizontal_grid);
6616b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, numItems);
6626b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
6636b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mOrientation = BaseGridView.HORIZONTAL;
6646b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mNumRows = numColumns;
6656b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        boolean[] focusable = new boolean[numItems];
6666b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        for (int i = 0; i < focusable.length; i++) {
6676b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu            focusable[i] = true;
6686b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        }
6696b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        for (int i = 0; i < startPos; i++) {
6706b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu            focusable[i] = false;
6716b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        }
6726b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS_FOCUSABLE, focusable);
6738c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
6746b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
675f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(0);
6766b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        assertTrue(mGridView.isFocused());
6776b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
678f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(numItems);
6796b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        assertTrue(mGridView.getLayoutManager().findViewByPosition(startPos).hasFocus());
6806b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu    }
6816b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
6826b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu    public void testTransferFocusable2() throws Throwable {
6836b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int numItems = 200;
6846b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int numColumns = 3;
6856b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int startPos = 10;
6866b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
6876b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mInstrumentation = getInstrumentation();
6886b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
6896b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
6906b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu                R.layout.horizontal_grid);
6916b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, numItems);
6926b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, true);
6936b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mOrientation = BaseGridView.HORIZONTAL;
6946b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mNumRows = numColumns;
6956b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        boolean[] focusable = new boolean[numItems];
6966b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        for (int i = 0; i < focusable.length; i++) {
6976b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu            focusable[i] = true;
6986b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        }
6996b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        for (int i = 0; i < startPos; i++) {
7006b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu            focusable[i] = false;
7016b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        }
7026b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS_FOCUSABLE, focusable);
7038c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
7046b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
705f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(0);
7066b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        assertTrue(mGridView.isFocused());
7076b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
708f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(numItems);
7096b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        assertTrue(mGridView.getLayoutManager().findViewByPosition(startPos).hasFocus());
7106b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu    }
711fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
7128c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    public void testNonFocusableLoseInFastLayout() throws Throwable {
713fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        mInstrumentation = getInstrumentation();
714fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
715fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
716fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu                R.layout.vertical_linear);
717fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        int[] items = new int[300];
718fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        for (int i = 0; i < items.length; i++) {
719fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu            items[i] = 480;
720fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        }
721fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
722fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
723fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_LAYOUT_ONFOCUS, true);
724fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        mOrientation = BaseGridView.VERTICAL;
725fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        mNumRows = 1;
726fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        int pressDown = 15;
727fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
7288c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
729fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
730fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        mGridView.setSelectedPositionSmooth(0);
731f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        waitForScrollIdle(mVerifyLayout);
732fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
733fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        for (int i = 0; i < pressDown; i++) {
734fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
735fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        }
736fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        waitForScrollIdle(mVerifyLayout);
737fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        assertFalse(mGridView.isFocused());
738fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
739fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu    }
740fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
7418c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    public void testSetSelectionWithDelta() throws Throwable {
7428c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mInstrumentation = getInstrumentation();
7438c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
7448c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
7458c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                R.layout.vertical_linear);
7468c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 300);
7478c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
7488c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mOrientation = BaseGridView.VERTICAL;
7498c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mNumRows = 1;
7508c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
7518c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
7528c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
7538c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
7548c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
7558c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(3);
7568c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
7578c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
7588c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
7598c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top1 = mGridView.getLayoutManager().findViewByPosition(3).getTop();
7608c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
761f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(1000);
7628c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
7638c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to position with delta
764f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(3, 100);
7658c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top2 = mGridView.getLayoutManager().findViewByPosition(3).getTop();
7668c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top2);
7678c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
7688c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to same position without delta, it will be reset
769f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(3, 0);
7708c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top3 = mGridView.getLayoutManager().findViewByPosition(3).getTop();
7718c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top3);
7728c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
7738c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item after last visible item
7748c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int lastVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
7758c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getLastVisibleIndex();
776f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(lastVisiblePos + 1, 100);
7778c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top4 = mGridView.getLayoutManager().findViewByPosition(lastVisiblePos + 1).getTop();
7788c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top4);
7798c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
7808c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item before first visible item
7818c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int firstVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
7828c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getFirstVisibleIndex();
783f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(firstVisiblePos - 1, 100);
7848c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top5 = mGridView.getLayoutManager().findViewByPosition(firstVisiblePos - 1).getTop();
7858c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top5);
7868c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
7878c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
788f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(50, 100);
7898c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top6 = mGridView.getLayoutManager().findViewByPosition(50).getTop();
7908c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top6);
7918c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
7928c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
7938c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
7948c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
7958c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(100);
7968c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
7978c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
7988c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
7998c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top7 = mGridView.getLayoutManager().findViewByPosition(100).getTop();
8008c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top7);
8018c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8028c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
803f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(10, 50);
8048c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top8 = mGridView.getLayoutManager().findViewByPosition(10).getTop();
8058c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 50, top8);
8068c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    }
8078c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8088c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    public void testSetSelectionWithDeltaInGrid() throws Throwable {
8098c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mInstrumentation = getInstrumentation();
8108c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
8118c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
8128c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                R.layout.vertical_grid);
8138c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 500);
8148c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, true);
8158c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mOrientation = BaseGridView.VERTICAL;
8168c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mNumRows = 3;
8178c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8188c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
8198c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8208c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
8218c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
8228c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(10);
8238c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
8248c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
8258c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
8268c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top1 = getCenterY(mGridView.getLayoutManager().findViewByPosition(10));
8278c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
828f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
8298c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8308c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to position with delta
831f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(20, 100);
8328c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top2 = getCenterY(mGridView.getLayoutManager().findViewByPosition(20));
8338c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top2);
8348c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8358c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to same position without delta, it will be reset
836f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(20, 0);
8378c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top3 = getCenterY(mGridView.getLayoutManager().findViewByPosition(20));
8388c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top3);
8398c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8408c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item after last visible item
8418c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int lastVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
8428c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getLastVisibleIndex();
843f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(lastVisiblePos + 1, 100);
8448c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top4 = getCenterY(mGridView.getLayoutManager().findViewByPosition(lastVisiblePos + 1));
8458c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        verifyMargin();
8468c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top4);
8478c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8488c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item before first visible item
8498c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int firstVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
8508c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getFirstVisibleIndex();
851f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(firstVisiblePos - 1, 100);
8528c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top5 = getCenterY(mGridView.getLayoutManager().findViewByPosition(firstVisiblePos - 1));
8538c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top5);
8548c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8558c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
856f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(100, 100);
8578c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top6 = getCenterY(mGridView.getLayoutManager().findViewByPosition(100));
8588c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top6);
8598c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8608c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
8618c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
8628c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
8638c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(200);
8648c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
8658c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
8668c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
8678c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Thread.sleep(500);
8688c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top7 = getCenterY(mGridView.getLayoutManager().findViewByPosition(200));
8698c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top7);
8708c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8718c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
872f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(10, 50);
8738c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top8 = getCenterY(mGridView.getLayoutManager().findViewByPosition(10));
8748c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 50, top8);
8758c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    }
8768c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8778c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8788c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    public void testSetSelectionWithDeltaInGrid1() throws Throwable {
8798c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mInstrumentation = getInstrumentation();
8808c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
8818c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
8828c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                R.layout.vertical_grid);
8838c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, new int[]{
8848c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                193,176,153,141,203,184,232,139,177,206,222,136,132,237,172,137,
8858c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                188,172,163,213,158,219,209,147,133,229,170,197,138,215,188,205,
8868c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                223,192,225,170,195,127,229,229,210,195,134,142,160,139,130,222,
8878c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                150,163,180,176,157,137,234,169,159,167,182,150,224,231,202,236,
8888c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                123,140,181,223,120,185,183,221,123,210,134,158,166,208,149,128,
8898c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                192,214,212,198,133,140,158,133,229,173,226,141,180,128,127,218,
8908c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                192,235,183,213,216,150,143,193,125,141,219,210,195,195,192,191,
8918c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                212,236,157,189,160,220,147,158,220,199,233,231,201,180,168,141,
8928c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                156,204,191,183,190,153,123,210,238,151,139,221,223,200,175,191,
8938c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                132,184,197,204,236,157,230,151,195,219,212,143,172,149,219,184,
8948c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                164,211,132,187,172,142,174,146,127,147,206,238,188,129,199,226,
8958c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                132,220,210,159,235,153,208,182,196,123,180,159,131,135,175,226,
8968c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                127,134,237,211,133,225,132,124,160,226,224,200,173,137,217,169,
8978c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                182,183,176,185,122,168,195,159,172,129,126,129,166,136,149,220,
8988c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                178,191,192,238,180,208,234,154,222,206,239,228,129,140,203,125,
8998c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                214,175,125,169,196,132,234,138,192,142,234,190,215,232,239,122,
9008c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                188,158,128,221,159,237,207,157,232,138,132,214,122,199,121,191,
9018c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                199,209,126,164,175,187,173,186,194,224,191,196,146,208,213,210,
9028c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                164,176,202,213,123,157,179,138,217,129,186,166,237,211,157,130,
9038c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                137,132,171,232,216,239,180,151,137,132,190,133,218,155,171,227,
9048c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                193,147,197,164,120,218,193,154,170,196,138,222,161,235,143,154,
9058c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                192,178,228,195,178,133,203,178,173,206,178,212,136,157,169,124,
9068c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                172,121,128,223,238,125,217,187,184,156,169,215,231,124,210,174,
9078c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                146,226,185,134,223,228,183,182,136,133,199,146,180,233,226,225,
9088c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                174,233,145,235,216,170,192,171,132,132,134,223,233,148,154,162,
9098c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                192,179,197,203,139,197,174,187,135,132,180,136,192,195,124,221,
9108c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                120,189,233,233,146,225,234,163,215,143,132,198,156,205,151,190,
9118c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                204,239,221,229,123,138,134,217,219,136,218,215,167,139,195,125,
9128c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                202,225,178,226,145,208,130,194,228,197,157,215,124,147,174,123,
9138c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                237,140,172,181,161,151,229,216,199,199,179,213,146,122,222,162,
9148c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                139,173,165,150,160,217,207,137,165,175,129,158,134,133,178,199,
9158c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                215,213,122,197
9168c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
9178c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, true);
9188c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mOrientation = BaseGridView.VERTICAL;
9198c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mNumRows = 3;
9208c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9218c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
9228c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9238c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
9248c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
9258c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(10);
9268c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
9278c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
9288c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
9298c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top1 = getCenterY(mGridView.getLayoutManager().findViewByPosition(10));
9308c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
931f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
9328c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9338c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to position with delta
934f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(20, 100);
9358c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top2 = getCenterY(mGridView.getLayoutManager().findViewByPosition(20));
9368c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top2);
9378c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9388c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to same position without delta, it will be reset
939f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(20, 0);
9408c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top3 = getCenterY(mGridView.getLayoutManager().findViewByPosition(20));
9418c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top3);
9428c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9438c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item after last visible item
9448c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int lastVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
9458c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getLastVisibleIndex();
946f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(lastVisiblePos + 1, 100);
9478c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top4 = getCenterY(mGridView.getLayoutManager().findViewByPosition(lastVisiblePos + 1));
9488c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        verifyMargin();
9498c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top4);
9508c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9518c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item before first visible item
9528c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int firstVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
9538c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getFirstVisibleIndex();
954f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(firstVisiblePos - 1, 100);
9558c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top5 = getCenterY(mGridView.getLayoutManager().findViewByPosition(firstVisiblePos - 1));
9568c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top5);
9578c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9588c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
959f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(100, 100);
9608c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top6 = getCenterY(mGridView.getLayoutManager().findViewByPosition(100));
9618c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top6);
9628c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9638c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
9648c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
9658c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
9668c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(200);
9678c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
9688c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
9698c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
9708c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Thread.sleep(500);
9718c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top7 = getCenterY(mGridView.getLayoutManager().findViewByPosition(200));
9728c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top7);
9738c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9748c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
975f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(10, 50);
9768c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top8 = getCenterY(mGridView.getLayoutManager().findViewByPosition(10));
9778c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 50, top8);
9788c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    }
979f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
980f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu    public void testSmoothScrollSelectionEvents() throws Throwable {
981f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mInstrumentation = getInstrumentation();
982f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
983f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
984f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                R.layout.vertical_grid);
985f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 500);
986f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
987f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mOrientation = BaseGridView.VERTICAL;
988f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mNumRows = 3;
989f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        initActivity(intent);
990f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
991f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        runTestOnUiThread(new Runnable() {
992f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            public void run() {
993f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                mGridView.setSelectedPositionSmooth(30);
994f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            }
995f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        });
996f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        waitForScrollIdle(mVerifyLayout);
997f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
998f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
999f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        final ArrayList<Integer> selectedPositions = new ArrayList<Integer>();
1000f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mGridView.setOnChildSelectedListener(new OnChildSelectedListener() {
1001f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            @Override
1002f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            public void onChildSelected(ViewGroup parent, View view, int position, long id) {
1003f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                selectedPositions.add(position);
1004f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            }
1005f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        });
1006f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1007f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        sendRepeatedKeys(10, KeyEvent.KEYCODE_DPAD_UP);
1008f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
1009f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        waitForScrollIdle(mVerifyLayout);
1010f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        // should only get childselected event for item 0 once
1011f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        assertTrue(selectedPositions.size() > 0);
1012f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        assertEquals(0, selectedPositions.get(selectedPositions.size() - 1).intValue());
1013f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        for (int i = selectedPositions.size() - 2; i >= 0; i--) {
1014f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            assertFalse(0 == selectedPositions.get(i).intValue());
1015f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        }
1016f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1017f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu    }
1018f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1019f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu    public void testSmoothScrollSelectionEventsLinear() throws Throwable {
1020f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mInstrumentation = getInstrumentation();
1021f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1022f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1023f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                R.layout.vertical_linear);
1024f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 500);
1025f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
1026f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mOrientation = BaseGridView.VERTICAL;
1027f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mNumRows = 1;
1028f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        initActivity(intent);
1029f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1030f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        runTestOnUiThread(new Runnable() {
1031f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            public void run() {
1032f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                mGridView.setSelectedPositionSmooth(10);
1033f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            }
1034f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        });
1035f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        waitForScrollIdle(mVerifyLayout);
1036f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
1037f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1038f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        final ArrayList<Integer> selectedPositions = new ArrayList<Integer>();
1039f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mGridView.setOnChildSelectedListener(new OnChildSelectedListener() {
1040f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            @Override
1041f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            public void onChildSelected(ViewGroup parent, View view, int position, long id) {
1042f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                selectedPositions.add(position);
1043f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            }
1044f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        });
1045f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1046f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        sendRepeatedKeys(10, KeyEvent.KEYCODE_DPAD_UP);
1047f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
1048f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        waitForScrollIdle(mVerifyLayout);
1049f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        // should only get childselected event for item 0 once
1050f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        assertTrue(selectedPositions.size() > 0);
1051f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        assertEquals(0, selectedPositions.get(selectedPositions.size() - 1).intValue());
1052f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        for (int i = selectedPositions.size() - 2; i >= 0; i--) {
1053f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            assertFalse(0 == selectedPositions.get(i).intValue());
1054f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        }
1055f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1056f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu    }
10577538845719cd1e588185ce9ae60320377862ef8dDake Gu
10587538845719cd1e588185ce9ae60320377862ef8dDake Gu    public void testScrollToNoneExisting() throws Throwable {
10597538845719cd1e588185ce9ae60320377862ef8dDake Gu        mInstrumentation = getInstrumentation();
10607538845719cd1e588185ce9ae60320377862ef8dDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
10617538845719cd1e588185ce9ae60320377862ef8dDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
10627538845719cd1e588185ce9ae60320377862ef8dDake Gu                R.layout.vertical_grid);
10637538845719cd1e588185ce9ae60320377862ef8dDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 100);
10647538845719cd1e588185ce9ae60320377862ef8dDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
10657538845719cd1e588185ce9ae60320377862ef8dDake Gu        mOrientation = BaseGridView.VERTICAL;
10667538845719cd1e588185ce9ae60320377862ef8dDake Gu        mNumRows = 3;
10677538845719cd1e588185ce9ae60320377862ef8dDake Gu        initActivity(intent);
10687538845719cd1e588185ce9ae60320377862ef8dDake Gu
10697538845719cd1e588185ce9ae60320377862ef8dDake Gu        runTestOnUiThread(new Runnable() {
10707538845719cd1e588185ce9ae60320377862ef8dDake Gu            public void run() {
10717538845719cd1e588185ce9ae60320377862ef8dDake Gu                mGridView.setSelectedPositionSmooth(99);
10727538845719cd1e588185ce9ae60320377862ef8dDake Gu            }
10737538845719cd1e588185ce9ae60320377862ef8dDake Gu        });
10747538845719cd1e588185ce9ae60320377862ef8dDake Gu        waitForScrollIdle(mVerifyLayout);
10757538845719cd1e588185ce9ae60320377862ef8dDake Gu        humanDelay(500);
10767538845719cd1e588185ce9ae60320377862ef8dDake Gu
10777538845719cd1e588185ce9ae60320377862ef8dDake Gu
10787538845719cd1e588185ce9ae60320377862ef8dDake Gu        runTestOnUiThread(new Runnable() {
10797538845719cd1e588185ce9ae60320377862ef8dDake Gu            public void run() {
10807538845719cd1e588185ce9ae60320377862ef8dDake Gu                mGridView.setSelectedPositionSmooth(50);
10817538845719cd1e588185ce9ae60320377862ef8dDake Gu            }
10827538845719cd1e588185ce9ae60320377862ef8dDake Gu        });
10837538845719cd1e588185ce9ae60320377862ef8dDake Gu        Thread.sleep(100);
10847538845719cd1e588185ce9ae60320377862ef8dDake Gu        runTestOnUiThread(new Runnable() {
10857538845719cd1e588185ce9ae60320377862ef8dDake Gu            public void run() {
10867538845719cd1e588185ce9ae60320377862ef8dDake Gu                mGridView.requestLayout();
10877538845719cd1e588185ce9ae60320377862ef8dDake Gu                mGridView.setSelectedPositionSmooth(0);
10887538845719cd1e588185ce9ae60320377862ef8dDake Gu            }
10897538845719cd1e588185ce9ae60320377862ef8dDake Gu        });
10907538845719cd1e588185ce9ae60320377862ef8dDake Gu        waitForScrollIdle(mVerifyLayout);
10917538845719cd1e588185ce9ae60320377862ef8dDake Gu        humanDelay(500);
10927538845719cd1e588185ce9ae60320377862ef8dDake Gu
10937538845719cd1e588185ce9ae60320377862ef8dDake Gu    }
10947538845719cd1e588185ce9ae60320377862ef8dDake Gu
10953a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu    public void testSmoothscrollerInterrupted() throws Throwable {
10963a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        mInstrumentation = getInstrumentation();
10973a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
10983a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
10993a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                R.layout.vertical_linear);
11003a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
11013a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        int[] items = new int[100];
11023a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        for (int i = 0; i < items.length; i++) {
11033a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            items[i] = 680;
11043a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        }
11053a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
11063a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
11073a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        mOrientation = BaseGridView.VERTICAL;
11083a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        mNumRows = 1;
11093a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu
11103a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        initActivity(intent);
11113a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu
11123a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        mGridView.setSelectedPositionSmooth(0);
11133a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        waitForScrollIdle(mVerifyLayout);
11143a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        assertTrue(mGridView.getChildAt(0).hasFocus());
11153a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu
11163a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        // Pressing lots of key to make sure smooth scroller is running
11173a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        for (int i = 0; i < 20; i++) {
11183a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
11193a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        }
11203a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        Thread.sleep(100);
11213a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        int total = 0;
11223a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        while (mGridView.getLayoutManager().isSmoothScrolling() ||
11233a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                mGridView.getScrollState() != BaseGridView.SCROLL_STATE_IDLE) {
11243a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            if ((total += 10) >= WAIT_FOR_SCROLL_IDLE_TIMEOUT_MS) {
11253a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                throw new RuntimeException("waitForScrollIdle Timeout");
11263a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            }
11273a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            try {
11283a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                // Repeatedly pressing to make sure pending keys does not drop to zero.
11293a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                Thread.sleep(10);
11303a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
11313a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            } catch (InterruptedException ex) {
11323a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                break;
11333a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            }
11343a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        }
11353a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu
11363a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        assertTrue("LinearSmoothScroller would not use many RV.smoothScrollBy() calls",
11373a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                ((VerticalGridViewEx) mGridView).mSmoothScrollByCalled < 10);
11383a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu    }
113957f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu
114057f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu    public void testSetNumRowsAndAddItem() throws Throwable {
114157f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        mInstrumentation = getInstrumentation();
114257f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
114357f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
114457f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu                R.layout.vertical_linear);
114557f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
114657f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        int[] items = new int[2];
114757f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        for (int i = 0; i < items.length; i++) {
114857f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu            items[i] = 300;
114957f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        }
115057f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
115157f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
115257f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        mOrientation = BaseGridView.VERTICAL;
115357f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        mNumRows = 1;
115457f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu
115557f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        initActivity(intent);
115657f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu
115757f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        mGridView.setSelectedPositionSmooth(0);
115857f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        waitForScrollIdle(mVerifyLayout);
115957f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu
116057f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        mActivity.addItems(items.length, new int[]{300});
116157f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu
116257f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        runTestOnUiThread(new Runnable() {
116357f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu            public void run() {
116457f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu                ((VerticalGridView) mGridView).setNumColumns(2);
116557f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu            }
116657f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        });
116757f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        Thread.sleep(1000);
116857f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        assertTrue(mGridView.getChildAt(2).getLeft() != mGridView.getChildAt(1).getLeft());
116957f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu    }
1170c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1171c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1172c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu    public void testRequestLayoutBugInLayout() throws Throwable {
1173c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        mInstrumentation = getInstrumentation();
1174c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1175c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1176c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                R.layout.vertical_linear);
1177c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.relative_layout);
1178c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
1179c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        int[] items = new int[100];
1180c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        for (int i = 0; i < items.length; i++) {
1181c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu            items[i] = 300;
1182c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        }
1183c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
1184c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
1185c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        mOrientation = BaseGridView.VERTICAL;
1186c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        mNumRows = 1;
1187c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1188c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        initActivity(intent);
1189c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1190c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        runTestOnUiThread(new Runnable() {
1191c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu            public void run() {
1192c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                mGridView.setSelectedPositionSmooth(1);
1193c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu            }
1194c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        });
1195c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        waitForScrollIdle(mVerifyLayout);
1196c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1197c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
1198c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        waitForScrollIdle(mVerifyLayout);
1199c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1200c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        assertEquals("Line 2", ((TextView) mGridView.findFocus()).getText().toString());
1201c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu    }
1202492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu
1203492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu
1204492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu    public void testChangeLayoutInChild() throws Throwable {
1205492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        mInstrumentation = getInstrumentation();
1206492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1207492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1208492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                R.layout.vertical_linear_wrap_content);
1209492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_LAYOUT_ONFOCUS, true);
1210492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        int[] items = new int[2];
1211492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        for (int i = 0; i < items.length; i++) {
1212492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu            items[i] = 300;
1213492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        }
1214492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
1215492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
1216492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        mOrientation = BaseGridView.VERTICAL;
1217492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        mNumRows = 1;
1218492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu
1219492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        initActivity(intent);
1220492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu
1221492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        runTestOnUiThread(new Runnable() {
1222492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu            public void run() {
1223492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                mGridView.setSelectedPositionSmooth(0);
1224492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu            }
1225492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        });
1226492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        waitForScrollIdle(mVerifyLayout);
1227492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        verifyMargin();
1228492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu
1229492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        runTestOnUiThread(new Runnable() {
1230492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu            public void run() {
1231492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                mGridView.setSelectedPositionSmooth(1);
1232492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu            }
1233492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        });
1234492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        waitForScrollIdle(mVerifyLayout);
1235492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        verifyMargin();
1236492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu    }
12371a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu
12381a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu
12391a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu    public void testZeroFixedSecondarySize() throws Throwable {
12401a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        mInstrumentation = getInstrumentation();
12411a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
12421a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
12431a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu                R.layout.vertical_linear_measured_with_zero);
12441a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        intent.putExtra(GridActivity.EXTRA_SECONDARY_SIZE_ZERO, true);
12451a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        int[] items = new int[2];
12461a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        for (int i = 0; i < items.length; i++) {
12471a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu            items[i] = 0;
12481a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        }
12491a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
12501a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
12511a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        mOrientation = BaseGridView.VERTICAL;
12521a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        mNumRows = 1;
12531a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu
12541a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        initActivity(intent);
12551a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu
12561a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu    }
12573bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
12583bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu    public void testChildStates() throws Throwable {
12593bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        mInstrumentation = getInstrumentation();
12603bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
12613bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.vertical_linear);
12623bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        int[] items = new int[100];
12633bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        for (int i = 0; i < items.length; i++) {
12643bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            items[i] = 200;
12653bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        }
12663bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
12673bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
12683bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_LAYOUT_ONFOCUS, true);
12693bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.selectable_text_view);
12703bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        mOrientation = BaseGridView.VERTICAL;
12713bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        mNumRows = 1;
12723bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
12733bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        initActivity(intent);
12743bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        mGridView.setSaveChildrenPolicy(VerticalGridView.SAVE_ALL_CHILD);
12753bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
127661e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        final SparseArray<Parcelable> container = new SparseArray<Parcelable>();
12773bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
12783bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        // 1 Save view states
12793bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        runTestOnUiThread(new Runnable() {
12803bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            public void run() {
12813bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                Selection.setSelection((Spannable)(((TextView) mGridView.getChildAt(0))
12823bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                        .getText()), 0, 1);
12833bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                Selection.setSelection((Spannable)(((TextView) mGridView.getChildAt(1))
12843bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                        .getText()), 0, 1);
12853bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                mGridView.saveHierarchyState(container);
12863bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            }
12873bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        });
12883bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
12893bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        // 2 Change view states
12903bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        runTestOnUiThread(new Runnable() {
12913bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            public void run() {
12923bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                Selection.setSelection((Spannable)(((TextView) mGridView.getChildAt(0))
12933bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                        .getText()), 1, 2);
12943bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                Selection.setSelection((Spannable)(((TextView) mGridView.getChildAt(1))
12953bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                        .getText()), 1, 2);
12963bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            }
12973bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        });
12983bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
12993bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        // 3 Detached and re-attached,  should still maintain state of (2)
13003bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        runTestOnUiThread(new Runnable() {
13013bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            public void run() {
13023bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                mGridView.setSelectedPositionSmooth(1);
13033bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            }
13043bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        });
13053bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        waitForScrollIdle(mVerifyLayout);
13063bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(0)).getSelectionStart(), 1);
13073bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(0)).getSelectionEnd(), 2);
13083bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(1)).getSelectionStart(), 1);
13093bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(1)).getSelectionEnd(), 2);
13103bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
13113bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        // 4 Recycled and rebound, should load state from (2)
13123bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        runTestOnUiThread(new Runnable() {
13133bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            public void run() {
13143bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                mGridView.setSelectedPositionSmooth(20);
13153bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            }
13163bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        });
13173bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        waitForScrollIdle(mVerifyLayout);
13183bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        runTestOnUiThread(new Runnable() {
13193bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            public void run() {
13203bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                mGridView.setSelectedPositionSmooth(0);
13213bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            }
13223bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        });
13233bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        waitForScrollIdle(mVerifyLayout);
13243bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(0)).getSelectionStart(), 1);
13253bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(0)).getSelectionEnd(), 2);
13263bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(1)).getSelectionStart(), 1);
13273bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(1)).getSelectionEnd(), 2);
13283bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu    }
13293bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
13303bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
133161e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu    public void testNoDispatchSaveChildState() throws Throwable {
133261e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        mInstrumentation = getInstrumentation();
133361e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
133461e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.vertical_linear);
133561e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        int[] items = new int[100];
133661e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        for (int i = 0; i < items.length; i++) {
133761e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            items[i] = 200;
133861e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        }
133961e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
134061e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
134161e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.selectable_text_view);
134261e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        mOrientation = BaseGridView.VERTICAL;
134361e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        mNumRows = 1;
134461e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
134561e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        initActivity(intent);
134661e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        mGridView.setSaveChildrenPolicy(VerticalGridView.SAVE_NO_CHILD);
134761e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
134861e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        final SparseArray<Parcelable> container = new SparseArray<Parcelable>();
134961e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
135061e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        // 1. Set text selection, save view states should do nothing on child
135161e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        runTestOnUiThread(new Runnable() {
135261e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            public void run() {
135361e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                for (int i = 0; i < mGridView.getChildCount(); i++) {
135461e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                    Selection.setSelection((Spannable)(((TextView) mGridView.getChildAt(i))
135561e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                            .getText()), 0, 1);
135661e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                }
135761e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                mGridView.saveHierarchyState(container);
135861e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            }
135961e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        });
136061e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
136161e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        // 2. clear the text selection
136261e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        runTestOnUiThread(new Runnable() {
136361e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            public void run() {
136461e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                for (int i = 0; i < mGridView.getChildCount(); i++) {
136561e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                    Selection.removeSelection((Spannable)(((TextView) mGridView.getChildAt(i))
136661e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                            .getText()));
136761e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                }
136861e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            }
136961e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        });
137061e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
137161e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        // 3. Restore view states should be a no-op for child
137261e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        runTestOnUiThread(new Runnable() {
137361e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            public void run() {
137461e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                mGridView.restoreHierarchyState(container);
137561e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                for (int i = 0; i < mGridView.getChildCount(); i++) {
137661e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                    assertEquals(-1, ((TextView) mGridView.getChildAt(i)).getSelectionStart());
137761e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                    assertEquals(-1, ((TextView) mGridView.getChildAt(i)).getSelectionEnd());
137861e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                }
137961e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            }
138061e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        });
138161e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu    }
138261e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
138308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
138408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static interface ViewTypeProvider {
138508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public int getViewType(int position);
138608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
138708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
138808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static interface ItemAlignmentFacetProvider {
138908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public ItemAlignmentFacet getItemAlignmentFacet(int viewType);
139008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
139108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
139208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static class TwoViewTypesProvider implements ViewTypeProvider {
139308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        static int VIEW_TYPE_FIRST = 1;
139408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        static int VIEW_TYPE_DEFAULT = 0;
139508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        @Override
139608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public int getViewType(int position) {
139708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (position == 0) {
139808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return VIEW_TYPE_FIRST;
139908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            } else {
140008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return VIEW_TYPE_DEFAULT;
140108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
140208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
140308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
140408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
140508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static class PositionItemAlignmentFacetProviderForRelativeLayout1
140608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            implements ItemAlignmentFacetProvider {
140708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        ItemAlignmentFacet mMultipleFacet;
140808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
140908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        PositionItemAlignmentFacetProviderForRelativeLayout1() {
141008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet = new ItemAlignmentFacet();
141108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            ItemAlignmentFacet.ItemAlignmentDef[] defs =
141208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                    new ItemAlignmentFacet.ItemAlignmentDef[2];
141308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0] = new ItemAlignmentFacet.ItemAlignmentDef();
141408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0].setItemAlignmentViewId(R.id.t1);
141508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1] = new ItemAlignmentFacet.ItemAlignmentDef();
141608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentViewId(R.id.t2);
141708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffsetPercent(100);
141808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffset(-10);
141908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet.setAlignmentDefs(defs);
142008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
142108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
142208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        @Override
142308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public ItemAlignmentFacet getItemAlignmentFacet(int position) {
142408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (position == 0) {
142508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return mMultipleFacet;
142608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            } else {
142708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return null;
142808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
142908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
143008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
143108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
143208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    public void testMultipleScrollPosition1() throws Throwable {
143308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mInstrumentation = getInstrumentation();
143408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
143508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
143608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                R.layout.vertical_linear);
143708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.relative_layout);
143808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
143908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int[] items = new int[100];
144008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        for (int i = 0; i < items.length; i++) {
144108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            items[i] = 300;
144208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
144308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
144408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
144508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_VIEWTYPEPROVIDER_CLASS,
144608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                TwoViewTypesProvider.class.getName());
144708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        // Set ItemAlignment for each ViewHolder and view type,  ViewHolder should
144808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        // override the view type settings.
144908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMALIGNMENTPROVIDER_CLASS,
145008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                PositionItemAlignmentFacetProviderForRelativeLayout1.class.getName());
145108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMALIGNMENTPROVIDER_VIEWTYPE_CLASS,
145208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                ViewTypePositionItemAlignmentFacetProviderForRelativeLayout2.class.getName());
145308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mOrientation = BaseGridView.VERTICAL;
145408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mNumRows = 1;
145508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
145608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        initActivity(intent);
145708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
145808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("First view is aligned with padding top",
145908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getPaddingTop(), mGridView.getChildAt(0).getTop());
146008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
146108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
146208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        waitForScrollIdle(mVerifyLayout);
146308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
146408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        final View v = mGridView.getChildAt(0);
146508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t1 = v.findViewById(R.id.t1);
146608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t1align = (t1.getTop() + t1.getBottom()) / 2;
146708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t2 = v.findViewById(R.id.t2);
146808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t2align = t2.getBottom() - 10;
146908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("Expected alignment for 2nd textview",
147008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getPaddingTop() - (t2align - t1align),
147108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                v.getTop());
147208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
147308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
147408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static class PositionItemAlignmentFacetProviderForRelativeLayout2 implements
147508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            ItemAlignmentFacetProvider {
147608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        ItemAlignmentFacet mMultipleFacet;
147708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
147808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        PositionItemAlignmentFacetProviderForRelativeLayout2() {
147908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet = new ItemAlignmentFacet();
148008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            ItemAlignmentFacet.ItemAlignmentDef[] defs = new ItemAlignmentFacet.ItemAlignmentDef[2];
148108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0] = new ItemAlignmentFacet.ItemAlignmentDef();
148208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0].setItemAlignmentViewId(R.id.t1);
148308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0].setItemAlignmentOffsetPercent(0);
148408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1] = new ItemAlignmentFacet.ItemAlignmentDef();
148508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentViewId(R.id.t2);
148608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffsetPercent(ItemAlignmentFacet.ITEM_ALIGN_OFFSET_PERCENT_DISABLED);
148708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffset(-10);
148808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet.setAlignmentDefs(defs);
148908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
149008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
149108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        @Override
149208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public ItemAlignmentFacet getItemAlignmentFacet(int position) {
149308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (position == 0) {
149408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return mMultipleFacet;
149508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            } else {
149608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return null;
149708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
149808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
149908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
150008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
150108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    public void testMultipleScrollPosition2() throws Throwable {
150208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mInstrumentation = getInstrumentation();
150308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
150408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.vertical_linear);
150508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.relative_layout);
150608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
150708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int[] items = new int[100];
150808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        for (int i = 0; i < items.length; i++) {
150908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            items[i] = 300;
151008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
151108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
151208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
151308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_VIEWTYPEPROVIDER_CLASS,
151408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                TwoViewTypesProvider.class.getName());
151508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMALIGNMENTPROVIDER_CLASS,
151608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                PositionItemAlignmentFacetProviderForRelativeLayout2.class.getName());
151708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mOrientation = BaseGridView.VERTICAL;
151808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mNumRows = 1;
151908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
152008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        initActivity(intent);
152108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
152208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("First view is aligned with padding top", mGridView.getPaddingTop(),
152308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getChildAt(0).getTop());
152408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
152508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
152608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        waitForScrollIdle(mVerifyLayout);
152708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
152808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        final View v = mGridView.getChildAt(0);
152908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t1 = v.findViewById(R.id.t1);
153008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t1align = t1.getTop();
153108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t2 = v.findViewById(R.id.t2);
153208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t2align = t2.getTop() - 10;
153308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("Expected alignment for 2nd textview",
153408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getPaddingTop() - (t2align - t1align), v.getTop());
153508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
153608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
153708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static class ViewTypePositionItemAlignmentFacetProviderForRelativeLayout2 implements
153808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            ItemAlignmentFacetProvider {
153908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        ItemAlignmentFacet mMultipleFacet;
154008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
154108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        ViewTypePositionItemAlignmentFacetProviderForRelativeLayout2() {
154208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet = new ItemAlignmentFacet();
154308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            ItemAlignmentFacet.ItemAlignmentDef[] defs = new ItemAlignmentFacet.ItemAlignmentDef[2];
154408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0] = new ItemAlignmentFacet.ItemAlignmentDef();
154508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0].setItemAlignmentViewId(R.id.t1);
154608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0].setItemAlignmentOffsetPercent(0);
154708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1] = new ItemAlignmentFacet.ItemAlignmentDef();
154808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentViewId(R.id.t2);
154908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffsetPercent(100);
155008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffset(-10);
155108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet.setAlignmentDefs(defs);
155208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
155308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
155408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        @Override
155508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public ItemAlignmentFacet getItemAlignmentFacet(int viewType) {
155608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (viewType == TwoViewTypesProvider.VIEW_TYPE_FIRST) {
155708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return mMultipleFacet;
155808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            } else {
155908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return null;
156008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
156108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
156208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
156308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
156408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    public void testMultipleScrollPosition3() throws Throwable {
156508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mInstrumentation = getInstrumentation();
156608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
156708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.vertical_linear);
156808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.relative_layout);
156908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
157008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int[] items = new int[100];
157108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        for (int i = 0; i < items.length; i++) {
157208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            items[i] = 300;
157308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
157408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
157508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
157608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_VIEWTYPEPROVIDER_CLASS,
157708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                TwoViewTypesProvider.class.getName());
157808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMALIGNMENTPROVIDER_VIEWTYPE_CLASS,
157908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                ViewTypePositionItemAlignmentFacetProviderForRelativeLayout2.class.getName());
158008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mOrientation = BaseGridView.VERTICAL;
158108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mNumRows = 1;
158208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
158308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        initActivity(intent);
158408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
158508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("First view is aligned with padding top", mGridView.getPaddingTop(),
158608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getChildAt(0).getTop());
158708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
158808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
158908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        waitForScrollIdle(mVerifyLayout);
159008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
159108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        final View v = mGridView.getChildAt(0);
159208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t1 = v.findViewById(R.id.t1);
159308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t1align = t1.getTop();
159408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t2 = v.findViewById(R.id.t2);
159508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t2align = t2.getBottom() - 10;
159608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("Expected alignment for 2nd textview",
159708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getPaddingTop() - (t2align - t1align), v.getTop());
159808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
159908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
1600db0b1afb71440b79923692d58adee982b5954838Dake Gu    public void testSelectionAndAddItemInOneCycle() throws Throwable {
1601db0b1afb71440b79923692d58adee982b5954838Dake Gu        mInstrumentation = getInstrumentation();
1602db0b1afb71440b79923692d58adee982b5954838Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1603db0b1afb71440b79923692d58adee982b5954838Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1604db0b1afb71440b79923692d58adee982b5954838Dake Gu                R.layout.vertical_linear);
1605db0b1afb71440b79923692d58adee982b5954838Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 0);
1606db0b1afb71440b79923692d58adee982b5954838Dake Gu        initActivity(intent);
1607db0b1afb71440b79923692d58adee982b5954838Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
1608db0b1afb71440b79923692d58adee982b5954838Dake Gu        mNumRows = 1;
1609db0b1afb71440b79923692d58adee982b5954838Dake Gu
1610db0b1afb71440b79923692d58adee982b5954838Dake Gu        runTestOnUiThread(new Runnable() {
1611db0b1afb71440b79923692d58adee982b5954838Dake Gu            public void run() {
1612db0b1afb71440b79923692d58adee982b5954838Dake Gu                mActivity.addItems(0, new int[]{300, 300});
1613db0b1afb71440b79923692d58adee982b5954838Dake Gu                mGridView.setSelectedPosition(0);
1614db0b1afb71440b79923692d58adee982b5954838Dake Gu            }
1615db0b1afb71440b79923692d58adee982b5954838Dake Gu        });
1616db0b1afb71440b79923692d58adee982b5954838Dake Gu        waitForTransientStateGone(null);
1617db0b1afb71440b79923692d58adee982b5954838Dake Gu        assertEquals(0, mGridView.getSelectedPosition());
1618db0b1afb71440b79923692d58adee982b5954838Dake Gu    }
1619db0b1afb71440b79923692d58adee982b5954838Dake Gu
1620db0b1afb71440b79923692d58adee982b5954838Dake Gu    public void testSelectionSmoothAndAddItemInOneCycle() throws Throwable {
1621db0b1afb71440b79923692d58adee982b5954838Dake Gu        mInstrumentation = getInstrumentation();
1622db0b1afb71440b79923692d58adee982b5954838Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1623db0b1afb71440b79923692d58adee982b5954838Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1624db0b1afb71440b79923692d58adee982b5954838Dake Gu                R.layout.vertical_linear);
1625db0b1afb71440b79923692d58adee982b5954838Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 0);
1626db0b1afb71440b79923692d58adee982b5954838Dake Gu        initActivity(intent);
1627db0b1afb71440b79923692d58adee982b5954838Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
1628db0b1afb71440b79923692d58adee982b5954838Dake Gu        mNumRows = 1;
1629db0b1afb71440b79923692d58adee982b5954838Dake Gu
1630db0b1afb71440b79923692d58adee982b5954838Dake Gu        runTestOnUiThread(new Runnable() {
1631db0b1afb71440b79923692d58adee982b5954838Dake Gu            public void run() {
1632db0b1afb71440b79923692d58adee982b5954838Dake Gu                mActivity.addItems(0, new int[]{300, 300});
1633db0b1afb71440b79923692d58adee982b5954838Dake Gu                mGridView.setSelectedPositionSmooth(0);
1634db0b1afb71440b79923692d58adee982b5954838Dake Gu            }
1635db0b1afb71440b79923692d58adee982b5954838Dake Gu        });
1636db0b1afb71440b79923692d58adee982b5954838Dake Gu        waitForTransientStateGone(null);
1637db0b1afb71440b79923692d58adee982b5954838Dake Gu        assertEquals(0, mGridView.getSelectedPosition());
1638db0b1afb71440b79923692d58adee982b5954838Dake Gu    }
163988dea72af6042049560140a70e059820dbb8f746Dake Gu
164088dea72af6042049560140a70e059820dbb8f746Dake Gu    public void testExtraLayoutSpace() throws Throwable {
164188dea72af6042049560140a70e059820dbb8f746Dake Gu        mInstrumentation = getInstrumentation();
164288dea72af6042049560140a70e059820dbb8f746Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
164388dea72af6042049560140a70e059820dbb8f746Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
164488dea72af6042049560140a70e059820dbb8f746Dake Gu                R.layout.vertical_linear);
164588dea72af6042049560140a70e059820dbb8f746Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 1000);
164688dea72af6042049560140a70e059820dbb8f746Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
164788dea72af6042049560140a70e059820dbb8f746Dake Gu        initActivity(intent);
164888dea72af6042049560140a70e059820dbb8f746Dake Gu
164988dea72af6042049560140a70e059820dbb8f746Dake Gu        final int windowSize = mGridView.getHeight();
165088dea72af6042049560140a70e059820dbb8f746Dake Gu        final int extraLayoutSize = windowSize;
165188dea72af6042049560140a70e059820dbb8f746Dake Gu        int itemLength = mActivity.mItemLengths[0];
165288dea72af6042049560140a70e059820dbb8f746Dake Gu        mOrientation = BaseGridView.VERTICAL;
165388dea72af6042049560140a70e059820dbb8f746Dake Gu        mNumRows = 1;
165488dea72af6042049560140a70e059820dbb8f746Dake Gu
165588dea72af6042049560140a70e059820dbb8f746Dake Gu        // add extra layout space
165688dea72af6042049560140a70e059820dbb8f746Dake Gu        runTestOnUiThread(new Runnable() {
165788dea72af6042049560140a70e059820dbb8f746Dake Gu            public void run() {
165888dea72af6042049560140a70e059820dbb8f746Dake Gu                mGridView.setExtraLayoutSpace(extraLayoutSize);
165988dea72af6042049560140a70e059820dbb8f746Dake Gu            }
166088dea72af6042049560140a70e059820dbb8f746Dake Gu        });
166188dea72af6042049560140a70e059820dbb8f746Dake Gu        Thread.sleep(50);
166288dea72af6042049560140a70e059820dbb8f746Dake Gu        View v;
166388dea72af6042049560140a70e059820dbb8f746Dake Gu        v = mGridView.getChildAt(mGridView.getChildCount() - 1);
166488dea72af6042049560140a70e059820dbb8f746Dake Gu        assertTrue(v.getTop() < windowSize + extraLayoutSize);
166588dea72af6042049560140a70e059820dbb8f746Dake Gu        assertTrue(v.getBottom() >= windowSize + extraLayoutSize -
166688dea72af6042049560140a70e059820dbb8f746Dake Gu                mGridView.getVerticalMargin());
166788dea72af6042049560140a70e059820dbb8f746Dake Gu
166888dea72af6042049560140a70e059820dbb8f746Dake Gu        mGridView.setSelectedPositionSmooth(150);
166988dea72af6042049560140a70e059820dbb8f746Dake Gu        waitForScrollIdle(mVerifyLayout);
167088dea72af6042049560140a70e059820dbb8f746Dake Gu        v = mGridView.getChildAt(0);
167188dea72af6042049560140a70e059820dbb8f746Dake Gu        assertTrue(v.getBottom() > - extraLayoutSize);
167288dea72af6042049560140a70e059820dbb8f746Dake Gu        assertTrue(v.getTop() <= -extraLayoutSize + mGridView.getVerticalMargin());
167388dea72af6042049560140a70e059820dbb8f746Dake Gu
167488dea72af6042049560140a70e059820dbb8f746Dake Gu        // clear extra layout space
167588dea72af6042049560140a70e059820dbb8f746Dake Gu        runTestOnUiThread(new Runnable() {
167688dea72af6042049560140a70e059820dbb8f746Dake Gu            public void run() {
167788dea72af6042049560140a70e059820dbb8f746Dake Gu                mGridView.setExtraLayoutSpace(0);
167888dea72af6042049560140a70e059820dbb8f746Dake Gu                verifyMargin();
167988dea72af6042049560140a70e059820dbb8f746Dake Gu            }
168088dea72af6042049560140a70e059820dbb8f746Dake Gu        });
168188dea72af6042049560140a70e059820dbb8f746Dake Gu        Thread.sleep(50);
168288dea72af6042049560140a70e059820dbb8f746Dake Gu        v = mGridView.getChildAt(mGridView.getChildCount() - 1);
168388dea72af6042049560140a70e059820dbb8f746Dake Gu        assertTrue(v.getTop() < windowSize);
168488dea72af6042049560140a70e059820dbb8f746Dake Gu        assertTrue(v.getBottom() >= windowSize - mGridView.getVerticalMargin());
168588dea72af6042049560140a70e059820dbb8f746Dake Gu    }
1686d1cab1b54104d55407335c5d649398635822fffdDake Gu
1687d1cab1b54104d55407335c5d649398635822fffdDake Gu    public void testAccessibility() throws Throwable {
1688d1cab1b54104d55407335c5d649398635822fffdDake Gu        mInstrumentation = getInstrumentation();
1689d1cab1b54104d55407335c5d649398635822fffdDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1690d1cab1b54104d55407335c5d649398635822fffdDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1691d1cab1b54104d55407335c5d649398635822fffdDake Gu                R.layout.vertical_linear);
1692d1cab1b54104d55407335c5d649398635822fffdDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 1000);
1693d1cab1b54104d55407335c5d649398635822fffdDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
1694d1cab1b54104d55407335c5d649398635822fffdDake Gu        initActivity(intent);
1695d1cab1b54104d55407335c5d649398635822fffdDake Gu        mOrientation = BaseGridView.VERTICAL;
1696d1cab1b54104d55407335c5d649398635822fffdDake Gu        mNumRows = 1;
1697d1cab1b54104d55407335c5d649398635822fffdDake Gu
1698d1cab1b54104d55407335c5d649398635822fffdDake Gu        assertTrue(0 == mGridView.getSelectedPosition());
1699d1cab1b54104d55407335c5d649398635822fffdDake Gu
1700d1cab1b54104d55407335c5d649398635822fffdDake Gu        final RecyclerViewAccessibilityDelegate delegateCompat = mGridView
1701d1cab1b54104d55407335c5d649398635822fffdDake Gu                .getCompatAccessibilityDelegate();
1702d1cab1b54104d55407335c5d649398635822fffdDake Gu        final AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
1703d1cab1b54104d55407335c5d649398635822fffdDake Gu        runTestOnUiThread(new Runnable() {
1704d1cab1b54104d55407335c5d649398635822fffdDake Gu            @Override
1705d1cab1b54104d55407335c5d649398635822fffdDake Gu            public void run() {
1706d1cab1b54104d55407335c5d649398635822fffdDake Gu                delegateCompat.onInitializeAccessibilityNodeInfo(mGridView, info);
1707d1cab1b54104d55407335c5d649398635822fffdDake Gu            }
1708d1cab1b54104d55407335c5d649398635822fffdDake Gu        });
1709d1cab1b54104d55407335c5d649398635822fffdDake Gu        assertTrue("test sanity", info.isScrollable());
1710d1cab1b54104d55407335c5d649398635822fffdDake Gu        runTestOnUiThread(new Runnable() {
1711d1cab1b54104d55407335c5d649398635822fffdDake Gu            @Override
1712d1cab1b54104d55407335c5d649398635822fffdDake Gu            public void run() {
1713d1cab1b54104d55407335c5d649398635822fffdDake Gu                delegateCompat.performAccessibilityAction(mGridView,
1714d1cab1b54104d55407335c5d649398635822fffdDake Gu                        AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD, null);
1715d1cab1b54104d55407335c5d649398635822fffdDake Gu            }
1716d1cab1b54104d55407335c5d649398635822fffdDake Gu        });
1717d1cab1b54104d55407335c5d649398635822fffdDake Gu        waitForScrollIdle(mVerifyLayout);
1718d1cab1b54104d55407335c5d649398635822fffdDake Gu        int selectedPosition1 = mGridView.getSelectedPosition();
1719d1cab1b54104d55407335c5d649398635822fffdDake Gu        assertTrue(0 < selectedPosition1);
1720d1cab1b54104d55407335c5d649398635822fffdDake Gu
1721d1cab1b54104d55407335c5d649398635822fffdDake Gu        runTestOnUiThread(new Runnable() {
1722d1cab1b54104d55407335c5d649398635822fffdDake Gu            @Override
1723d1cab1b54104d55407335c5d649398635822fffdDake Gu            public void run() {
1724d1cab1b54104d55407335c5d649398635822fffdDake Gu                delegateCompat.onInitializeAccessibilityNodeInfo(mGridView, info);
1725d1cab1b54104d55407335c5d649398635822fffdDake Gu            }
1726d1cab1b54104d55407335c5d649398635822fffdDake Gu        });
1727d1cab1b54104d55407335c5d649398635822fffdDake Gu        assertTrue("test sanity", info.isScrollable());
1728d1cab1b54104d55407335c5d649398635822fffdDake Gu        runTestOnUiThread(new Runnable() {
1729d1cab1b54104d55407335c5d649398635822fffdDake Gu            @Override
1730d1cab1b54104d55407335c5d649398635822fffdDake Gu            public void run() {
1731d1cab1b54104d55407335c5d649398635822fffdDake Gu                delegateCompat.performAccessibilityAction(mGridView,
1732d1cab1b54104d55407335c5d649398635822fffdDake Gu                        AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD, null);
1733d1cab1b54104d55407335c5d649398635822fffdDake Gu            }
1734d1cab1b54104d55407335c5d649398635822fffdDake Gu        });
1735d1cab1b54104d55407335c5d649398635822fffdDake Gu        waitForScrollIdle(mVerifyLayout);
1736d1cab1b54104d55407335c5d649398635822fffdDake Gu        int selectedPosition2 = mGridView.getSelectedPosition();
1737d1cab1b54104d55407335c5d649398635822fffdDake Gu        assertTrue(selectedPosition2 < selectedPosition1);
1738d1cab1b54104d55407335c5d649398635822fffdDake Gu    }
1739d1cab1b54104d55407335c5d649398635822fffdDake Gu
1740062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu}
1741