ListOfItemsTallerThanScreenTest.java revision 1d3165f10b12165f02b7015ac1a817c5f60e6399
1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.widget.listview.arrowscroll;
18
19import android.test.ActivityInstrumentationTestCase;
20import android.test.suitebuilder.annotation.LargeTest;
21import android.test.suitebuilder.annotation.MediumTest;
22import android.widget.ListView;
23import android.view.View;
24import android.view.KeyEvent;
25import android.widget.listview.ListOfItemsTallerThanScreen;
26
27public class ListOfItemsTallerThanScreenTest
28        extends ActivityInstrumentationTestCase<ListOfItemsTallerThanScreen> {
29
30    private ListView mListView;
31    private ListOfItemsTallerThanScreen mActivity;
32
33
34    protected void setUp() throws Exception {
35        super.setUp();
36        mActivity = getActivity();
37        mListView = getActivity().getListView();
38    }
39
40    public ListOfItemsTallerThanScreenTest() {
41        super("com.android.frameworks.coretests", ListOfItemsTallerThanScreen.class);
42    }
43
44    @MediumTest
45    public void testPreconditions() {
46        assertNotNull(mListView);
47        assertEquals("should only be one visible child", 1, mListView.getChildCount());
48        final int amountOffScreen = mListView.getChildAt(0).getBottom() - (mListView.getBottom() - mListView.getListPaddingBottom());
49        assertTrue("must be more than max scroll off screen for this test to work",
50                amountOffScreen > mListView.getMaxScrollAmount());
51    }
52
53    @MediumTest
54    public void testScrollDownAcrossItem() {
55        final View view = mListView.getSelectedView();
56        assertTrue(view.isSelected());
57
58        assertEquals(mListView.getListPaddingTop(),
59                view.getTop());
60
61        assertTrue("view must be taller than screen for this test to be worth anything",
62                view.getBottom() > mListView.getBottom());
63
64        // scroll down until next view is peeking ahead
65        int numScrollsUntilNextViewVisible = getNumDownPressesToScrollDownAcrossSelected();
66
67        for (int i = 0; i < numScrollsUntilNextViewVisible; i++) {
68            assertEquals("after " + i + " down scrolls across tall item",
69                    mListView.getListPaddingTop() - mListView.getMaxScrollAmount() * i,
70                    view.getTop());
71            sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
72        }
73
74        // at this point, next view should be on screen peeking ahead, but we haven't given
75        // it selection yet
76        assertEquals("child count", 2, mListView.getChildCount());
77        assertEquals("selected position", 0, mListView.getSelectedItemPosition());
78        assertTrue("same view should be selected", view.isSelected());
79        final View peekingView = mListView.getChildAt(1);
80        assertEquals(view.getBottom(), peekingView.getTop());
81    }
82
83    @MediumTest
84    public void testScrollDownToNextItem() {
85        final int numPresses = getNumDownPressesToScrollDownAcrossSelected();
86        assertEquals(1, mListView.getChildCount());
87
88        for (int i = 0; i < numPresses; i++) {
89            sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
90        }
91        // remember top of peeking child
92        final int topOfPeekingNext = mListView.getChildAt(1).getTop();
93
94        // next view is peeking, now press one more time
95        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
96
97        // old view should not have selection
98        assertFalse(mListView.getChildAt(0).isSelected());
99
100        // next view should now have selection, and be scrolled another a third of the list
101        // height
102        assertEquals(2, mListView.getChildCount());
103        final View next = mListView.getChildAt(1);
104        assertTrue("has selection", next.isSelected());
105        assertEquals(topOfPeekingNext - (mListView.getMaxScrollAmount()), next.getTop());
106    }
107
108    @MediumTest
109    public void testScrollFirstItemOffScreen() {
110        int numDownsToGetFirstItemOffScreen =
111                (mListView.getSelectedView().getHeight() / mListView.getMaxScrollAmount()) + 1;
112
113        for (int i = 0; i < numDownsToGetFirstItemOffScreen; i++) {
114            sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
115        }
116        getInstrumentation().waitForIdleSync();
117
118        assertEquals("should be at next item",
119                1, mListView.getSelectedItemPosition());
120
121        final int listTop = mListView.getTop() + mListView.getListPaddingTop();
122        assertTrue("top of selected view should be above top of list",
123                mListView.getSelectedView().getTop() < listTop);
124
125        assertEquals("off screen item shouldn't be a child of list view",
126                1, mListView.getChildCount());
127    }
128
129    @LargeTest
130    public void testScrollDownToLastItem() {
131        final int numItems = mListView.getAdapter().getCount();
132
133        int maxDowns = 20;
134        while (mListView.getSelectedItemPosition() < (numItems - 1)) {
135            sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
136            if (--maxDowns <= 0) {
137                fail("couldn't get to last item within 20 down arrows");
138            }
139        }
140        getInstrumentation().waitForIdleSync();
141
142        // press down enough times to get to bottom of last item
143        final int numDownsLeft = getNumDownPressesToScrollDownAcrossSelected();
144        assertTrue(numDownsLeft > 0);
145        for (int i = 0; i < numDownsLeft; i++) {
146            sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
147        }
148        // one more time to get across last item
149        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
150        getInstrumentation().waitForIdleSync();
151
152        assertEquals(numItems - 1, mListView.getSelectedItemPosition());
153        final int realBottom = mListView.getHeight() - mListView.getListPaddingBottom();
154        assertEquals(realBottom, mListView.getSelectedView().getBottom());
155
156        assertEquals("views scrolled off screen should be removed from view group",
157                1, mListView.getChildCount());
158    }
159
160    @MediumTest
161    public void testScrollUpAcrossFirstItem() {
162        final int listTop = mListView.getListPaddingTop();
163        assertEquals(listTop, mListView.getSelectedView().getTop());
164        final int numPresses = getNumDownPressesToScrollDownAcrossSelected();
165        for (int i = 0; i < numPresses; i++) {
166            sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
167        }
168        assertEquals(2, mListView.getChildCount());
169        for (int i = 0; i < numPresses; i++) {
170            sendKeys(KeyEvent.KEYCODE_DPAD_UP);
171            assertEquals(1, mListView.getChildCount());
172        }
173        assertEquals(listTop, mListView.getSelectedView().getTop());
174    }
175
176    /**
177     * Assuming the selected view is overlapping the bottom edge, how many times
178     * do I have to press down to get beyond it so that either:
179     * a) the next view is peeking in
180     * b) the selected view is the last item in the list, and we are scrolled to the bottom
181     * @return
182     */
183    private int getNumDownPressesToScrollDownAcrossSelected() {
184        View selected = mListView.getSelectedView();
185        int realBottom = mListView.getBottom() - mListView.getListPaddingBottom();
186        assertTrue("view should be overlapping bottom",
187                selected.getBottom() > realBottom);
188        assertTrue("view should be overlapping bottom",
189                selected.getTop() < realBottom);
190
191        int pixelsOffScreen = selected.getBottom() - realBottom;
192        return (pixelsOffScreen / mListView.getMaxScrollAmount()) + 1;
193    }
194
195}
196