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;
20346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powellimport android.widget.Scroller;
21346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
22346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell/**
23346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell * Provides access to new {@link android.widget.Scroller Scroller} APIs when available.
24346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell *
25346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell * <p>This class provides a platform version-independent mechanism for obeying the
26346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell * current device's preferred scroll physics and fling behavior. It offers a subset of
27346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell * the APIs from Scroller or OverScroller.</p>
28346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell */
29346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powellclass ScrollerCompat {
30346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    Scroller mScroller;
31346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
32346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    static class ScrollerCompatImplIcs extends ScrollerCompat {
33346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell        public ScrollerCompatImplIcs(Context context) {
34346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell            super(context);
35346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell        }
36346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
37346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell        @Override
38346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell        public float getCurrVelocity() {
39346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell            return ScrollerCompatIcs.getCurrVelocity(mScroller);
40346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell        }
41346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
42346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
43346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    public static ScrollerCompat from(Context context) {
44346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell        if (android.os.Build.VERSION.SDK_INT >= 14) {
45346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell            return new ScrollerCompatImplIcs(context);
46346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell        }
47346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell        return new ScrollerCompat(context);
48346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
49346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
50346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    ScrollerCompat(Context context) {
51346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell        mScroller = new Scroller(context);
52346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
53346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
54346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    /**
55346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * Returns whether the scroller has finished scrolling.
56346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *
57346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @return True if the scroller has finished scrolling, false otherwise.
58346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     */
59346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    public boolean isFinished() {
60346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell        return mScroller.isFinished();
61346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
62346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
63346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    /**
64346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * Returns how long the scroll event will take, in milliseconds.
65346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *
66346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @return The duration of the scroll in milliseconds.
67346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     */
68346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    public int getDuration() {
69346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell        return mScroller.getDuration();
70346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
71346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
72346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    /**
73346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * Returns the current X offset in the scroll.
74346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *
75346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @return The new X offset as an absolute distance from the origin.
76346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     */
77346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    public int getCurrX() {
78346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell        return mScroller.getCurrX();
79346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
80346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
81346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    /**
82346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * Returns the current Y offset in the scroll.
83346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *
84346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @return The new Y offset as an absolute distance from the origin.
85346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     */
86346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    public int getCurrY() {
87346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell        return mScroller.getCurrY();
88346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
89346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
90346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    /**
91346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * Returns the current velocity.
92346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *
93346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * TODO: Approximate a sane result for older platform versions. Right now
94346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * this will return 0 for platforms earlier than ICS. This is acceptable
95346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * at the moment only since it is only used for EdgeEffect, which is also only
96346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * present in ICS+, and ScrollerCompat is not public.
97346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *
98346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @return The original velocity less the deceleration. Result may be
99346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * negative.
100346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     */
101346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    public float getCurrVelocity() {
102346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell        return 0;
103346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
104346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
105346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    /**
106346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * Call this when you want to know the new location.  If it returns true,
107346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * the animation is not yet finished.  loc will be altered to provide the
108346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * new location.
109346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     */
110346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    public boolean computeScrollOffset() {
111346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell        return mScroller.computeScrollOffset();
112346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
113346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
114346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    /**
115346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * Start scrolling by providing a starting point and the distance to travel.
116346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * The scroll will use the default value of 250 milliseconds for the
117346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * duration.
118346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *
119346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param startX Starting horizontal scroll offset in pixels. Positive
120346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        numbers will scroll the content to the left.
121346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param startY Starting vertical scroll offset in pixels. Positive numbers
122346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        will scroll the content up.
123346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param dx Horizontal distance to travel. Positive numbers will scroll the
124346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        content to the left.
125346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param dy Vertical distance to travel. Positive numbers will scroll the
126346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        content up.
127346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     */
128346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    public void startScroll(int startX, int startY, int dx, int dy) {
129346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell        mScroller.startScroll(startX, startY, dx, dy);
130346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
131346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
132346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    /**
133346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * Start scrolling by providing a starting point and the distance to travel.
134346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *
135346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param startX Starting horizontal scroll offset in pixels. Positive
136346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        numbers will scroll the content to the left.
137346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param startY Starting vertical scroll offset in pixels. Positive numbers
138346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        will scroll the content up.
139346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param dx Horizontal distance to travel. Positive numbers will scroll the
140346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        content to the left.
141346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param dy Vertical distance to travel. Positive numbers will scroll the
142346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        content up.
143346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param duration Duration of the scroll in milliseconds.
144346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     */
145346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    public void startScroll(int startX, int startY, int dx, int dy, int duration) {
146346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell        mScroller.startScroll(startX, startY, dx, dy, duration);
147346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
148346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
149346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    /**
150346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * Start scrolling based on a fling gesture. The distance travelled will
151346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * depend on the initial velocity of the fling.
152346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *
153346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param startX Starting point of the scroll (X)
154346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param startY Starting point of the scroll (Y)
155346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param velocityX Initial velocity of the fling (X) measured in pixels per
156346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        second.
157346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param velocityY Initial velocity of the fling (Y) measured in pixels per
158346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        second
159346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param minX Minimum X value. The scroller will not scroll past this
160346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        point.
161346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param maxX Maximum X value. The scroller will not scroll past this
162346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        point.
163346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param minY Minimum Y value. The scroller will not scroll past this
164346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        point.
165346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * @param maxY Maximum Y value. The scroller will not scroll past this
166346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     *        point.
167346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     */
168346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    public void fling(int startX, int startY, int velocityX, int velocityY,
169346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell            int minX, int maxX, int minY, int maxY) {
170346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell        mScroller.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY);
171346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
172346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell
173346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    /**
174346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * Stops the animation. Contrary to {@link #forceFinished(boolean)},
175346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * aborting the animating cause the scroller to move to the final x and y
176346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     * position
177346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell     */
178346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    public void abortAnimation() {
179346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell        mScroller.abortAnimation();
180346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell    }
181346e2f2390f0d743fd10e7d01a015df6b32292cdAdam Powell}
182