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