1346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell/*
2346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell * Copyright (C) 2012 The Android Open Source Project
3346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell *
4346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell * Licensed under the Apache License, Version 2.0 (the "License");
5346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell * you may not use this file except in compliance with the License.
6346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell * You may obtain a copy of the License at
7346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell *
8346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell *      http://www.apache.org/licenses/LICENSE-2.0
9346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell *
10346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell * Unless required by applicable law or agreed to in writing, software
11346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell * distributed under the License is distributed on an "AS IS" BASIS,
12346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell * See the License for the specific language governing permissions and
14346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell * limitations under the License.
15346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell */
16346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
17346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powellpackage android.support.v4.widget;
18346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
19346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powellimport android.content.Context;
20b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powellimport android.os.Build;
21009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powellimport android.view.animation.AnimationUtils;
22c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powellimport android.view.animation.Interpolator;
23346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powellimport android.widget.Scroller;
24346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
25346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell/**
26346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell * Provides access to new {@link android.widget.Scroller Scroller} APIs when available.
27346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell *
28346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell * <p>This class provides a platform version-independent mechanism for obeying the
29346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell * current device's preferred scroll physics and fling behavior. It offers a subset of
30346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell * the APIs from Scroller or OverScroller.</p>
31346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell */
32b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powellpublic class ScrollerCompat {
33009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell    private static final String TAG = "ScrollerCompat";
34009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell
35b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell    Object mScroller;
36009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell    ScrollerCompatImpl mImpl;
37346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
38b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell    interface ScrollerCompatImpl {
39b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        Object createScroller(Context context, Interpolator interpolator);
40b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        boolean isFinished(Object scroller);
41b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        int getCurrX(Object scroller);
42b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        int getCurrY(Object scroller);
43b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        float getCurrVelocity(Object scroller);
44b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        boolean computeScrollOffset(Object scroller);
45b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        void startScroll(Object scroller, int startX, int startY, int dx, int dy);
46b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        void startScroll(Object scroller, int startX, int startY, int dx, int dy, int duration);
47b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        void fling(Object scroller, int startX, int startY, int velX, int velY,
48b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell                int minX, int maxX, int minY, int maxY);
49b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        void fling(Object scroller, int startX, int startY, int velX, int velY,
50b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell                int minX, int maxX, int minY, int maxY, int overX, int overY);
51b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        void abortAnimation(Object scroller);
52b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        void notifyHorizontalEdgeReached(Object scroller, int startX, int finalX, int overX);
53b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        void notifyVerticalEdgeReached(Object scroller, int startY, int finalY, int overY);
54b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        boolean isOverScrolled(Object scroller);
556580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell        int getFinalX(Object scroller);
566580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell        int getFinalY(Object scroller);
57b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell    }
58b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
59009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell    static final int CHASE_FRAME_TIME = 16; // ms per target frame
60009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell
61b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell    static class ScrollerCompatImplBase implements ScrollerCompatImpl {
62b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
63b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public Object createScroller(Context context, Interpolator interpolator) {
64b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            return interpolator != null ?
65b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell                    new Scroller(context, interpolator) : new Scroller(context);
66b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
67b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
68b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
69b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public boolean isFinished(Object scroller) {
7048e3efd2e7bc8057212d3936a239838ecf6e40a9Yigit Boyar            return ((Scroller) scroller).isFinished();
71b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
72b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
73b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
74b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public int getCurrX(Object scroller) {
75b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            return ((Scroller) scroller).getCurrX();
76b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
77b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
78b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
79b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public int getCurrY(Object scroller) {
80b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            return ((Scroller) scroller).getCurrY();
81b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
82b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
83b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
84b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public float getCurrVelocity(Object scroller) {
85b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            return 0;
86b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
87b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
88b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
89b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public boolean computeScrollOffset(Object scroller) {
90009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell            final Scroller s = (Scroller) scroller;
9148e3efd2e7bc8057212d3936a239838ecf6e40a9Yigit Boyar            return s.computeScrollOffset();
92b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
93b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
94b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
95b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public void startScroll(Object scroller, int startX, int startY, int dx, int dy) {
96b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            ((Scroller) scroller).startScroll(startX, startY, dx, dy);
97b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
98b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
99b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
100b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public void startScroll(Object scroller, int startX, int startY, int dx, int dy,
101b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell                int duration) {
102b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            ((Scroller) scroller).startScroll(startX, startY, dx, dy, duration);
103b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
104b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
105b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
106b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public void fling(Object scroller, int startX, int startY, int velX, int velY,
107b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell                int minX, int maxX, int minY, int maxY) {
108b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            ((Scroller) scroller).fling(startX, startY, velX, velY, minX, maxX, minY, maxY);
109b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
110b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
111b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
112b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public void fling(Object scroller, int startX, int startY, int velX, int velY,
113b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell                int minX, int maxX, int minY, int maxY, int overX, int overY) {
114b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            ((Scroller) scroller).fling(startX, startY, velX, velY, minX, maxX, minY, maxY);
115b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
116b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
117b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
118b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public void abortAnimation(Object scroller) {
119b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            ((Scroller) scroller).abortAnimation();
120b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
121b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
122b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
123b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public void notifyHorizontalEdgeReached(Object scroller, int startX, int finalX,
124b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell                int overX) {
125b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            // No-op
126b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
127b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
128b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
129b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public void notifyVerticalEdgeReached(Object scroller, int startY, int finalY, int overY) {
130b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            // No-op
131b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
132b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
133b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
134b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public boolean isOverScrolled(Object scroller) {
135b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            // Always false
136b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            return false;
137b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
1386580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell
1396580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell        @Override
1406580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell        public int getFinalX(Object scroller) {
1416580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell            return ((Scroller) scroller).getFinalX();
1426580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell        }
1436580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell
1446580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell        @Override
1456580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell        public int getFinalY(Object scroller) {
1466580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell            return ((Scroller) scroller).getFinalY();
1476580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell        }
148b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell    }
149b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
150b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell    static class ScrollerCompatImplGingerbread implements ScrollerCompatImpl {
151b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
152b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public Object createScroller(Context context, Interpolator interpolator) {
153b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            return ScrollerCompatGingerbread.createScroller(context, interpolator);
154b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
155b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
156b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
157b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public boolean isFinished(Object scroller) {
15848e3efd2e7bc8057212d3936a239838ecf6e40a9Yigit Boyar            return ScrollerCompatGingerbread.isFinished(scroller);
159b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
160b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
161b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
162b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public int getCurrX(Object scroller) {
163b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            return ScrollerCompatGingerbread.getCurrX(scroller);
164b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
165b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
166b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
167b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public int getCurrY(Object scroller) {
168b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            return ScrollerCompatGingerbread.getCurrY(scroller);
169b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
170b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
171b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
172b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public float getCurrVelocity(Object scroller) {
173b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            return 0;
174b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
175b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
176b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
177b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public boolean computeScrollOffset(Object scroller) {
17848e3efd2e7bc8057212d3936a239838ecf6e40a9Yigit Boyar            return ScrollerCompatGingerbread.computeScrollOffset(scroller);
179b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
180b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
181b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
182b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public void startScroll(Object scroller, int startX, int startY, int dx, int dy) {
183b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            ScrollerCompatGingerbread.startScroll(scroller, startX, startY, dx, dy);
184b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
185b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
186b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
187b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public void startScroll(Object scroller, int startX, int startY, int dx, int dy,
188b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell                int duration) {
189b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            ScrollerCompatGingerbread.startScroll(scroller, startX, startY, dx, dy, duration);
190346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell        }
191346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
192346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell        @Override
193b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public void fling(Object scroller, int startX, int startY, int velX, int velY,
194b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell                int minX, int maxX, int minY, int maxY) {
195b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            ScrollerCompatGingerbread.fling(scroller, startX, startY, velX, velY,
196b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell                    minX, maxX, minY, maxY);
197b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
198b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
199b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
200b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public void fling(Object scroller, int startX, int startY, int velX, int velY,
201b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell                int minX, int maxX, int minY, int maxY, int overX, int overY) {
202b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            ScrollerCompatGingerbread.fling(scroller, startX, startY, velX, velY,
203b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell                    minX, maxX, minY, maxY, overX, overY);
204b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
205b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
206b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
207b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public void abortAnimation(Object scroller) {
208b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            ScrollerCompatGingerbread.abortAnimation(scroller);
209b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
210b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
211b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
212b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public void notifyHorizontalEdgeReached(Object scroller, int startX, int finalX,
213b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell                int overX) {
214b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            ScrollerCompatGingerbread.notifyHorizontalEdgeReached(scroller, startX, finalX, overX);
215b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
216b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
217b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
218b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public void notifyVerticalEdgeReached(Object scroller, int startY, int finalY, int overY) {
219b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            ScrollerCompatGingerbread.notifyVerticalEdgeReached(scroller, startY, finalY, overY);
220b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
221b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
222b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
223b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public boolean isOverScrolled(Object scroller) {
224b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            return ScrollerCompatGingerbread.isOverScrolled(scroller);
225b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
2266580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell
2276580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell        @Override
2286580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell        public int getFinalX(Object scroller) {
2296580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell            return ScrollerCompatGingerbread.getFinalX(scroller);
2306580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell        }
2316580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell
2326580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell        @Override
2336580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell        public int getFinalY(Object scroller) {
2346580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell            return ScrollerCompatGingerbread.getFinalY(scroller);
2356580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell        }
236b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell    }
237b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
238b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell    static class ScrollerCompatImplIcs extends ScrollerCompatImplGingerbread {
239b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        @Override
240b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        public float getCurrVelocity(Object scroller) {
241b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            return ScrollerCompatIcs.getCurrVelocity(scroller);
242b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell        }
243b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell    }
244b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
245c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell    public static ScrollerCompat create(Context context) {
246c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        return create(context, null);
247c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell    }
248c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
249c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell    public static ScrollerCompat create(Context context, Interpolator interpolator) {
250c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        return new ScrollerCompat(context, interpolator);
251346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
252346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
253c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell    ScrollerCompat(Context context, Interpolator interpolator) {
2544ad0efc06631e6e35d8ced424c36438bf5827569Yigit Boyar        this(Build.VERSION.SDK_INT, context, interpolator);
2554ad0efc06631e6e35d8ced424c36438bf5827569Yigit Boyar
2564ad0efc06631e6e35d8ced424c36438bf5827569Yigit Boyar    }
2574ad0efc06631e6e35d8ced424c36438bf5827569Yigit Boyar
2584ad0efc06631e6e35d8ced424c36438bf5827569Yigit Boyar    /**
2594ad0efc06631e6e35d8ced424c36438bf5827569Yigit Boyar     * Private constructer where API version can be provided.
2604ad0efc06631e6e35d8ced424c36438bf5827569Yigit Boyar     * Useful for unit testing.
2614ad0efc06631e6e35d8ced424c36438bf5827569Yigit Boyar     */
2624ad0efc06631e6e35d8ced424c36438bf5827569Yigit Boyar    private ScrollerCompat(int apiVersion, Context context, Interpolator interpolator) {
2634ad0efc06631e6e35d8ced424c36438bf5827569Yigit Boyar        if (apiVersion >= 14) { // ICS
264009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell            mImpl = new ScrollerCompatImplIcs();
2654ad0efc06631e6e35d8ced424c36438bf5827569Yigit Boyar        } else if (apiVersion>= 9) { // Gingerbread
266009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell            mImpl = new ScrollerCompatImplGingerbread();
267009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell        } else {
268009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell            mImpl = new ScrollerCompatImplBase();
269009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell        }
270009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell        mScroller = mImpl.createScroller(context, interpolator);
271346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
272346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
273346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    /**
274346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * Returns whether the scroller has finished scrolling.
275346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *
276346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @return True if the scroller has finished scrolling, false otherwise.
277346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     */
278346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    public boolean isFinished() {
279009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell        return mImpl.isFinished(mScroller);
280346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
281346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
282346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    /**
283346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * Returns the current X offset in the scroll.
284346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *
285346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @return The new X offset as an absolute distance from the origin.
286346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     */
287346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    public int getCurrX() {
288009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell        return mImpl.getCurrX(mScroller);
289346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
290346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
291346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    /**
292346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * Returns the current Y offset in the scroll.
293346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *
294346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @return The new Y offset as an absolute distance from the origin.
295346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     */
296346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    public int getCurrY() {
297009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell        return mImpl.getCurrY(mScroller);
298346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
299346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
300346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    /**
3016580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell     * @return The final X position for the scroll in progress, if known.
3026580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell     */
3036580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell    public int getFinalX() {
304009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell        return mImpl.getFinalX(mScroller);
3056580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell    }
3066580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell
3076580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell    /**
3086580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell     * @return The final Y position for the scroll in progress, if known.
3096580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell     */
3106580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell    public int getFinalY() {
311009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell        return mImpl.getFinalY(mScroller);
3126580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell    }
3136580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell
3146580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell    /**
315b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * Returns the current velocity on platform versions that support it.
316346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *
317b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * <p>The device must support at least API level 14 (Ice Cream Sandwich).
318b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * On older platform versions this method will return 0. This method should
319b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * only be used as input for nonessential visual effects such as {@link EdgeEffectCompat}.</p>
320346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *
321346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @return The original velocity less the deceleration. Result may be
322346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * negative.
323346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     */
324346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    public float getCurrVelocity() {
325009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell        return mImpl.getCurrVelocity(mScroller);
326346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
327346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
328346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    /**
329346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * Call this when you want to know the new location.  If it returns true,
330346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * the animation is not yet finished.  loc will be altered to provide the
331346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * new location.
332346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     */
333346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    public boolean computeScrollOffset() {
334009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell        return mImpl.computeScrollOffset(mScroller);
335346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
336346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
337346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    /**
338346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * Start scrolling by providing a starting point and the distance to travel.
339346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * The scroll will use the default value of 250 milliseconds for the
340346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * duration.
341346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *
342346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param startX Starting horizontal scroll offset in pixels. Positive
343346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        numbers will scroll the content to the left.
344346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param startY Starting vertical scroll offset in pixels. Positive numbers
345346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        will scroll the content up.
346346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param dx Horizontal distance to travel. Positive numbers will scroll the
347346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        content to the left.
348346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param dy Vertical distance to travel. Positive numbers will scroll the
349346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        content up.
350346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     */
351346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    public void startScroll(int startX, int startY, int dx, int dy) {
352009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell        mImpl.startScroll(mScroller, startX, startY, dx, dy);
353346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
354346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
355346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    /**
356346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * Start scrolling by providing a starting point and the distance to travel.
357346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *
358346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param startX Starting horizontal scroll offset in pixels. Positive
359346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        numbers will scroll the content to the left.
360346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param startY Starting vertical scroll offset in pixels. Positive numbers
361346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        will scroll the content up.
362346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param dx Horizontal distance to travel. Positive numbers will scroll the
363346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        content to the left.
364346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param dy Vertical distance to travel. Positive numbers will scroll the
365346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        content up.
366346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param duration Duration of the scroll in milliseconds.
367346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     */
368346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    public void startScroll(int startX, int startY, int dx, int dy, int duration) {
369009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell        mImpl.startScroll(mScroller, startX, startY, dx, dy, duration);
370346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
371346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
372346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    /**
373346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * Start scrolling based on a fling gesture. The distance travelled will
374346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * depend on the initial velocity of the fling.
375346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *
376346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param startX Starting point of the scroll (X)
377346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param startY Starting point of the scroll (Y)
378346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param velocityX Initial velocity of the fling (X) measured in pixels per
379346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        second.
380346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param velocityY Initial velocity of the fling (Y) measured in pixels per
381346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        second
382346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param minX Minimum X value. The scroller will not scroll past this
383346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        point.
384346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param maxX Maximum X value. The scroller will not scroll past this
385346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        point.
386346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param minY Minimum Y value. The scroller will not scroll past this
387346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        point.
388346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param maxY Maximum Y value. The scroller will not scroll past this
389346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        point.
390346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     */
391346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    public void fling(int startX, int startY, int velocityX, int velocityY,
392346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell            int minX, int maxX, int minY, int maxY) {
393009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell        mImpl.fling(mScroller, startX, startY, velocityX, velocityY, minX, maxX, minY, maxY);
394346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
395346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
396346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    /**
397b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * Start scrolling based on a fling gesture. The distance travelled will
398b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * depend on the initial velocity of the fling.
399b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     *
400b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * @param startX Starting point of the scroll (X)
401b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * @param startY Starting point of the scroll (Y)
402b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * @param velocityX Initial velocity of the fling (X) measured in pixels per
403b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     *        second.
404b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * @param velocityY Initial velocity of the fling (Y) measured in pixels per
405b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     *        second
406b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * @param minX Minimum X value. The scroller will not scroll past this
407b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     *        point.
408b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * @param maxX Maximum X value. The scroller will not scroll past this
409b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     *        point.
410b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * @param minY Minimum Y value. The scroller will not scroll past this
411b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     *        point.
412b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * @param maxY Maximum Y value. The scroller will not scroll past this
413b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     *        point.
414b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * @param overX Overfling range. If > 0, horizontal overfling in either
415b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     *            direction will be possible.
416b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * @param overY Overfling range. If > 0, vertical overfling in either
417b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     *            direction will be possible.
418b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     */
419b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell    public void fling(int startX, int startY, int velocityX, int velocityY,
420b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell            int minX, int maxX, int minY, int maxY, int overX, int overY) {
421009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell        mImpl.fling(mScroller, startX, startY, velocityX, velocityY,
422b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell                minX, maxX, minY, maxY, overX, overY);
423b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell    }
424b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
425b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell    /**
426b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * Stops the animation. Aborting the animation causes the scroller to move to the final x and y
427b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * position.
428346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     */
429346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    public void abortAnimation() {
430009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell        mImpl.abortAnimation(mScroller);
431b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell    }
432b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
433b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
434b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell    /**
435b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * Notify the scroller that we've reached a horizontal boundary.
436b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * Normally the information to handle this will already be known
437b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * when the animation is started, such as in a call to one of the
438b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * fling functions. However there are cases where this cannot be known
439b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * in advance. This function will transition the current motion and
440b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * animate from startX to finalX as appropriate.
441b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     *
442b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * @param startX Starting/current X position
443b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * @param finalX Desired final X position
444b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * @param overX Magnitude of overscroll allowed. This should be the maximum
445b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     *              desired distance from finalX. Absolute value - must be positive.
446b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     */
447b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell    public void notifyHorizontalEdgeReached(int startX, int finalX, int overX) {
448009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell        mImpl.notifyHorizontalEdgeReached(mScroller, startX, finalX, overX);
449b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell    }
450b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
451b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell    /**
452b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * Notify the scroller that we've reached a vertical boundary.
453b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * Normally the information to handle this will already be known
454b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * when the animation is started, such as in a call to one of the
455b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * fling functions. However there are cases where this cannot be known
456b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * in advance. This function will animate a parabolic motion from
457b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * startY to finalY.
458b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     *
459b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * @param startY Starting/current Y position
460b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * @param finalY Desired final Y position
461b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * @param overY Magnitude of overscroll allowed. This should be the maximum
462b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     *              desired distance from finalY. Absolute value - must be positive.
463b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     */
464b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell    public void notifyVerticalEdgeReached(int startY, int finalY, int overY) {
465009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell        mImpl.notifyVerticalEdgeReached(mScroller, startY, finalY, overY);
466b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell    }
467b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell
468b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell    /**
469b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * Returns whether the current Scroller is currently returning to a valid position.
470b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * Valid bounds were provided by the
471b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * {@link #fling(int, int, int, int, int, int, int, int, int, int)} method.
472b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     *
473b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * One should check this value before calling
474b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * {@link #startScroll(int, int, int, int)} as the interpolation currently in progress
475b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * to restore a valid position will then be stopped. The caller has to take into account
476b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * the fact that the started scroll will start from an overscrolled position.
477b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     *
478b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     * @return true when the current position is overscrolled and in the process of
479b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     *         interpolating back to a valid value.
480b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell     */
481b9e34c7d443082d5ee2b90a0e6788523d8df0df1Adam Powell    public boolean isOverScrolled() {
482009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell        return mImpl.isOverScrolled(mScroller);
483346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
484346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell}
485