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.view.KeyEvent;
     22 import android.view.View;
     23 import android.widget.ListView;
     24 import android.widget.listview.ListOfItemsTallerThanScreen;
     25 
     26 public class ListOfItemsTallerThanScreenTest
     27         extends ActivityInstrumentationTestCase2<ListOfItemsTallerThanScreen> {
     28 
     29     private ListView mListView;
     30     private ListOfItemsTallerThanScreen mActivity;
     31 
     32 
     33     protected void setUp() throws Exception {
     34         super.setUp();
     35         mActivity = getActivity();
     36         mListView = getActivity().getListView();
     37     }
     38 
     39     public ListOfItemsTallerThanScreenTest() {
     40         super(ListOfItemsTallerThanScreen.class);
     41     }
     42 
     43     @MediumTest
     44     public void testPreconditions() {
     45         assertNotNull(mListView);
     46         assertEquals("should only be one visible child", 1, mListView.getChildCount());
     47         final int amountOffScreen = mListView.getChildAt(0).getBottom() - (mListView.getBottom() - mListView.getListPaddingBottom());
     48         assertTrue("must be more than max scroll off screen for this test to work",
     49                 amountOffScreen > mListView.getMaxScrollAmount());
     50     }
     51 
     52     @MediumTest
     53     public void testScrollDownAcrossItem() {
     54         final View view = mListView.getSelectedView();
     55         assertTrue(view.isSelected());
     56 
     57         assertEquals(mListView.getListPaddingTop(),
     58                 view.getTop());
     59 
     60         assertTrue("view must be taller than screen for this test to be worth anything",
     61                 view.getBottom() > mListView.getBottom());
     62 
     63         // scroll down until next view is peeking ahead
     64         int numScrollsUntilNextViewVisible = getNumDownPressesToScrollDownAcrossSelected();
     65 
     66         for (int i = 0; i < numScrollsUntilNextViewVisible; i++) {
     67             assertEquals("after " + i + " down scrolls across tall item",
     68                     mListView.getListPaddingTop() - mListView.getMaxScrollAmount() * i,
     69                     view.getTop());
     70             sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
     71         }
     72 
     73         // at this point, next view should be on screen peeking ahead, but we haven't given
     74         // it selection yet
     75         assertEquals("child count", 2, mListView.getChildCount());
     76         assertEquals("selected position", 0, mListView.getSelectedItemPosition());
     77         assertTrue("same view should be selected", view.isSelected());
     78         final View peekingView = mListView.getChildAt(1);
     79         assertEquals(view.getBottom(), peekingView.getTop());
     80     }
     81 
     82     @MediumTest
     83     public void testScrollDownToNextItem() {
     84         final int numPresses = getNumDownPressesToScrollDownAcrossSelected();
     85         assertEquals(1, mListView.getChildCount());
     86 
     87         for (int i = 0; i < numPresses; i++) {
     88             sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
     89         }
     90         // remember top of peeking child
     91         final int topOfPeekingNext = mListView.getChildAt(1).getTop();
     92 
     93         // next view is peeking, now press one more time
     94         sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
     95 
     96         // old view should not have selection
     97         assertFalse(mListView.getChildAt(0).isSelected());
     98 
     99         // next view should now have selection, and be scrolled another a third of the list
    100         // height
    101         assertEquals(2, mListView.getChildCount());
    102         final View next = mListView.getChildAt(1);
    103         assertTrue("has selection", next.isSelected());
    104         assertEquals(topOfPeekingNext - (mListView.getMaxScrollAmount()), next.getTop());
    105     }
    106 
    107     @MediumTest
    108     public void testScrollFirstItemOffScreen() {
    109         int numDownsToGetFirstItemOffScreen =
    110                 (mListView.getSelectedView().getHeight() / mListView.getMaxScrollAmount()) + 1;
    111 
    112         for (int i = 0; i < numDownsToGetFirstItemOffScreen; i++) {
    113             sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
    114         }
    115         getInstrumentation().waitForIdleSync();
    116 
    117         assertEquals("should be at next item",
    118                 1, mListView.getSelectedItemPosition());
    119 
    120         final int listTop = mListView.getTop() + mListView.getListPaddingTop();
    121         assertTrue("top of selected view should be above top of list",
    122                 mListView.getSelectedView().getTop() < listTop);
    123 
    124         assertEquals("off screen item shouldn't be a child of list view",
    125                 1, mListView.getChildCount());
    126     }
    127 
    128     @MediumTest
    129     public void testScrollDownToLastItem() {
    130         final int numItems = mListView.getAdapter().getCount();
    131 
    132         int maxDowns = 20;
    133         while (mListView.getSelectedItemPosition() < (numItems - 1)) {
    134             sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
    135             if (--maxDowns <= 0) {
    136                 fail("couldn't get to last item within 20 down arrows");
    137             }
    138         }
    139         getInstrumentation().waitForIdleSync();
    140 
    141         // press down enough times to get to bottom of last item
    142         final int numDownsLeft = getNumDownPressesToScrollDownAcrossSelected();
    143         assertTrue(numDownsLeft > 0);
    144         for (int i = 0; i < numDownsLeft; i++) {
    145             sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
    146         }
    147         // one more time to get across last item
    148         sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
    149         getInstrumentation().waitForIdleSync();
    150 
    151         assertEquals(numItems - 1, mListView.getSelectedItemPosition());
    152         final int realBottom = mListView.getHeight() - mListView.getListPaddingBottom();
    153         assertEquals(realBottom, mListView.getSelectedView().getBottom());
    154 
    155         assertEquals("views scrolled off screen should be removed from view group",
    156                 1, mListView.getChildCount());
    157     }
    158 
    159     @MediumTest
    160     public void testScrollUpAcrossFirstItem() {
    161         final int listTop = mListView.getListPaddingTop();
    162         assertEquals(listTop, mListView.getSelectedView().getTop());
    163         final int numPresses = getNumDownPressesToScrollDownAcrossSelected();
    164         for (int i = 0; i < numPresses; i++) {
    165             sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
    166         }
    167         assertEquals(2, mListView.getChildCount());
    168         for (int i = 0; i < numPresses; i++) {
    169             sendKeys(KeyEvent.KEYCODE_DPAD_UP);
    170             assertEquals(1, mListView.getChildCount());
    171         }
    172         assertEquals(listTop, mListView.getSelectedView().getTop());
    173     }
    174 
    175     /**
    176      * Assuming the selected view is overlapping the bottom edge, how many times
    177      * do I have to press down to get beyond it so that either:
    178      * a) the next view is peeking in
    179      * b) the selected view is the last item in the list, and we are scrolled to the bottom
    180      * @return
    181      */
    182     private int getNumDownPressesToScrollDownAcrossSelected() {
    183         View selected = mListView.getSelectedView();
    184         int realBottom = mListView.getBottom() - mListView.getListPaddingBottom();
    185         assertTrue("view should be overlapping bottom",
    186                 selected.getBottom() > realBottom);
    187         assertTrue("view should be overlapping bottom",
    188                 selected.getTop() < realBottom);
    189 
    190         int pixelsOffScreen = selected.getBottom() - realBottom;
    191         return (pixelsOffScreen / mListView.getMaxScrollAmount()) + 1;
    192     }
    193 
    194 }
    195