1 /* 2 * Copyright (C) 2013 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 androidx.core.widget; 18 19 import android.view.View; 20 import android.widget.ListView; 21 22 import org.jspecify.annotations.NonNull; 23 24 /** 25 * An implementation of {@link AutoScrollHelper} that knows how to scroll 26 * through a {@link ListView}. 27 */ 28 public class ListViewAutoScrollHelper extends AutoScrollHelper { 29 @SuppressWarnings("HidingField") 30 private final ListView mTarget; 31 ListViewAutoScrollHelper(@onNull ListView target)32 public ListViewAutoScrollHelper(@NonNull ListView target) { 33 super(target); 34 35 mTarget = target; 36 } 37 38 @Override scrollTargetBy(int deltaX, int deltaY)39 public void scrollTargetBy(int deltaX, int deltaY) { 40 mTarget.scrollListBy(deltaY); 41 } 42 43 @Override canTargetScrollHorizontally(int direction)44 public boolean canTargetScrollHorizontally(int direction) { 45 // List do not scroll horizontally. 46 return false; 47 } 48 49 @Override canTargetScrollVertically(int direction)50 public boolean canTargetScrollVertically(int direction) { 51 final ListView target = mTarget; 52 final int itemCount = target.getCount(); 53 if (itemCount == 0) { 54 return false; 55 } 56 57 final int childCount = target.getChildCount(); 58 final int firstPosition = target.getFirstVisiblePosition(); 59 final int lastPosition = firstPosition + childCount; 60 61 if (direction > 0) { 62 // Are we already showing the entire last item? 63 if (lastPosition >= itemCount) { 64 final View lastView = target.getChildAt(childCount - 1); 65 if (lastView.getBottom() <= target.getHeight()) { 66 return false; 67 } 68 } 69 } else if (direction < 0) { 70 // Are we already showing the entire first item? 71 if (firstPosition <= 0) { 72 final View firstView = target.getChildAt(0); 73 if (firstView.getTop() >= 0) { 74 return false; 75 } 76 } 77 } else { 78 // The behavior for direction 0 is undefined and we can return 79 // whatever we want. 80 return false; 81 } 82 83 return true; 84 } 85 } 86