1eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette/* 2eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette * Copyright (C) 2013 The Android Open Source Project 3eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette * 4eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette * Licensed under the Apache License, Version 2.0 (the "License"); 5eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette * you may not use this file except in compliance with the License. 6eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette * You may obtain a copy of the License at 7eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette * 8eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette * http://www.apache.org/licenses/LICENSE-2.0 9eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette * 10eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette * Unless required by applicable law or agreed to in writing, software 11eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette * distributed under the License is distributed on an "AS IS" BASIS, 12eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette * See the License for the specific language governing permissions and 14eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette * limitations under the License. 15eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette */ 16eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette 17eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverettepackage android.support.v4.widget; 18eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette 19eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viveretteimport android.view.View; 20eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viveretteimport android.widget.ListView; 21eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette 22eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette/** 23eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette * An implementation of {@link AutoScrollHelper} that knows how to scroll 24eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette * through a {@link ListView}. 25eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette */ 26eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverettepublic class ListViewAutoScrollHelper extends AutoScrollHelper { 27eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette private final ListView mTarget; 28eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette 29eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette public ListViewAutoScrollHelper(ListView target) { 30eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette super(target); 31eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette 32eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette mTarget = target; 33eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette } 34eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette 35eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette @Override 36504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette public void scrollTargetBy(int deltaX, int deltaY) { 37504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette final ListView target = mTarget; 38504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette final int firstPosition = target.getFirstVisiblePosition(); 39504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette if (firstPosition == ListView.INVALID_POSITION) { 40504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette return; 41504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette } 42504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette 43504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette final View firstView = target.getChildAt(0); 44504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette if (firstView == null) { 45504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette return; 46504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette } 47504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette 48504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette final int newTop = firstView.getTop() - deltaY; 49504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette target.setSelectionFromTop(firstPosition, newTop); 50504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette } 51504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette 52504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette @Override 53504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette public boolean canTargetScrollHorizontally(int direction) { 54504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette // List do not scroll horizontally. 55504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette return false; 56504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette } 57504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette 58504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette @Override 59504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette public boolean canTargetScrollVertically(int direction) { 60eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette final ListView target = mTarget; 61eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette final int itemCount = target.getCount(); 6226a583f97faa79045ef31a7ddd50d73da5afe9d2Alan Viverette if (itemCount == 0) { 6326a583f97faa79045ef31a7ddd50d73da5afe9d2Alan Viverette return false; 6426a583f97faa79045ef31a7ddd50d73da5afe9d2Alan Viverette } 6526a583f97faa79045ef31a7ddd50d73da5afe9d2Alan Viverette 66eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette final int childCount = target.getChildCount(); 67eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette final int firstPosition = target.getFirstVisiblePosition(); 68eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette final int lastPosition = firstPosition + childCount; 69eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette 70504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette if (direction > 0) { 71eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette // Are we already showing the entire last item? 72eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette if (lastPosition >= itemCount) { 73eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette final View lastView = target.getChildAt(childCount - 1); 74eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette if (lastView.getBottom() <= target.getHeight()) { 75eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette return false; 76eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette } 77eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette } 78504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette } else if (direction < 0) { 79eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette // Are we already showing the entire first item? 80eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette if (firstPosition <= 0) { 81eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette final View firstView = target.getChildAt(0); 82eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette if (firstView.getTop() >= 0) { 83eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette return false; 84eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette } 85eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette } 86eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette } else { 87504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette // The behavior for direction 0 is undefined and we can return 88504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette // whatever we want. 89504f6b9c6bcc6b2f50b2aaf4cf9b9bcae7e0e755Alan Viverette return false; 90eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette } 91eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette 92eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette return true; 93eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette } 94eb38a77f4c2b50da454ce0720ceb056f4932f4aeAlan Viverette} 95