Home | History | Annotate | Download | only in arrowscroll
      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 
     17 package android.widget.listview.arrowscroll;
     18 
     19 import android.test.ActivityInstrumentationTestCase2;
     20 import android.test.suitebuilder.annotation.MediumTest;
     21 import android.test.suitebuilder.annotation.Suppress;
     22 import android.view.KeyEvent;
     23 import android.view.View;
     24 import android.widget.ListView;
     25 import android.widget.listview.ListOfItemsTallerThanScreen;
     26 
     27 public class ListOfItemsTallerThanScreenTest
     28         extends ActivityInstrumentationTestCase2<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(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     @Suppress // Failing.
    110     public void testScrollFirstItemOffScreen() {
    111         int numDownsToGetFirstItemOffScreen =
    112                 (mListView.getSelectedView().getHeight() / mListView.getMaxScrollAmount()) + 1;
    113 
    114         for (int i = 0; i < numDownsToGetFirstItemOffScreen; i++) {
    115             sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
    116         }
    117         getInstrumentation().waitForIdleSync();
    118 
    119         assertEquals("should be at next item",
    120                 1, mListView.getSelectedItemPosition());
    121 
    122         final int listTop = mListView.getTop() + mListView.getListPaddingTop();
    123         assertTrue("top of selected view should be above top of list",
    124                 mListView.getSelectedView().getTop() < listTop);
    125 
    126         assertEquals("off screen item shouldn't be a child of list view",
    127                 1, mListView.getChildCount());
    128     }
    129 
    130     @MediumTest
    131     public void testScrollDownToLastItem() {
    132         final int numItems = mListView.getAdapter().getCount();
    133 
    134         int maxDowns = 20;
    135         while (mListView.getSelectedItemPosition() < (numItems - 1)) {
    136             sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
    137             if (--maxDowns <= 0) {
    138                 fail("couldn't get to last item within 20 down arrows");
    139             }
    140         }
    141         getInstrumentation().waitForIdleSync();
    142 
    143         // press down enough times to get to bottom of last item
    144         final int numDownsLeft = getNumDownPressesToScrollDownAcrossSelected();
    145         assertTrue(numDownsLeft > 0);
    146         for (int i = 0; i < numDownsLeft; i++) {
    147             sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
    148         }
    149         // one more time to get across last item
    150         sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
    151         getInstrumentation().waitForIdleSync();
    152 
    153         assertEquals(numItems - 1, mListView.getSelectedItemPosition());
    154         final int realBottom = mListView.getHeight() - mListView.getListPaddingBottom();
    155         assertEquals(realBottom, mListView.getSelectedView().getBottom());
    156 
    157         assertEquals("views scrolled off screen should be removed from view group",
    158                 1, mListView.getChildCount());
    159     }
    160 
    161     @MediumTest
    162     public void testScrollUpAcrossFirstItem() {
    163         final int listTop = mListView.getListPaddingTop();
    164         assertEquals(listTop, mListView.getSelectedView().getTop());
    165         final int numPresses = getNumDownPressesToScrollDownAcrossSelected();
    166         for (int i = 0; i < numPresses; i++) {
    167             sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
    168         }
    169         assertEquals(2, mListView.getChildCount());
    170         for (int i = 0; i < numPresses; i++) {
    171             sendKeys(KeyEvent.KEYCODE_DPAD_UP);
    172             assertEquals(1, mListView.getChildCount());
    173         }
    174         assertEquals(listTop, mListView.getSelectedView().getTop());
    175     }
    176 
    177     /**
    178      * Assuming the selected view is overlapping the bottom edge, how many times
    179      * do I have to press down to get beyond it so that either:
    180      * a) the next view is peeking in
    181      * b) the selected view is the last item in the list, and we are scrolled to the bottom
    182      * @return
    183      */
    184     private int getNumDownPressesToScrollDownAcrossSelected() {
    185         View selected = mListView.getSelectedView();
    186         int realBottom = mListView.getBottom() - mListView.getListPaddingBottom();
    187         assertTrue("view should be overlapping bottom",
    188                 selected.getBottom() > realBottom);
    189         assertTrue("view should be overlapping bottom",
    190                 selected.getTop() < realBottom);
    191 
    192         int pixelsOffScreen = selected.getBottom() - realBottom;
    193         return (pixelsOffScreen / mListView.getMaxScrollAmount()) + 1;
    194     }
    195 
    196 }
    197