155 lines
6.3 KiB
Plaintext
155 lines
6.3 KiB
Plaintext
page.title=Animating a Scroll Gesture
|
|
parent.title=Using Touch Gestures
|
|
parent.link=index.html
|
|
|
|
trainingnavtop=true
|
|
next.title=Handling Multi-Touch Gestures
|
|
next.link=multi.html
|
|
|
|
@jd:body
|
|
|
|
<div id="tb-wrapper">
|
|
<div id="tb">
|
|
|
|
<!-- table of contents -->
|
|
<h2>This lesson teaches you to</h2>
|
|
<ol>
|
|
<li><a href="#scroll">Implement Touch-Based Scrolling</a></li>
|
|
</ol>
|
|
|
|
<!-- other docs (NOT javadocs) -->
|
|
<h2>You should also read</h2>
|
|
|
|
<ul>
|
|
<li><a href="http://developer.android.com/guide/topics/ui/ui-events.html">Input Events</a> API Guide
|
|
</li>
|
|
<li><a href="{@docRoot}guide/topics/sensors/sensors_overview.html">Sensors Overview</a></li>
|
|
<li><a href="http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html">Making Sense of Multitouch</a> blog post</li>
|
|
<li><a href="{@docRoot}training/custom-views/making-interactive.html">Making the View Interactive</a> </li>
|
|
<li>Design Guide for <a href="{@docRoot}design/patterns/gestures.html">Gestures</a></li>
|
|
<li>Design Guide for <a href="{@docRoot}design/style/touch-feedback.html">Touch Feedback</a></li>
|
|
</ul>
|
|
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<p>In Android, scrolling is typically achieved by using the
|
|
{@link android.widget.ScrollView}
|
|
class. Any standard layout that might extend beyond the bounds of its container should be
|
|
nested in a {@link android.widget.ScrollView} to provide a scrollable view that's
|
|
managed by the framework. Implementing a custom scroller should only be
|
|
necessary for special scenarios. This lesson describes such a scenario: displaying
|
|
a scrolling effect in response to touch gestures using <em>scrollers</em>.
|
|
|
|
|
|
<p>You can use scrollers ({@link android.widget.Scroller} or {@link
|
|
android.widget.OverScroller}) to collect the data you need to produce a
|
|
scrolling animation in response to a touch event.</p>
|
|
|
|
<p>A scroller is used to animate scrolling over time, using platform-standard
|
|
scrolling physics (friction, velocity, etc.). The scroller itself doesn't
|
|
actually draw anything. Scrollers track scroll offsets for you over time, but
|
|
they don't automatically apply those positions to your view. It's your
|
|
responsibility to get and apply new coordinates at a rate that will make the
|
|
scrolling animation look smooth.</p>
|
|
|
|
<p class="note"><strong>Note:</strong> You generally only need to use scrollers
|
|
when implementing scrolling yourself. {@link android.widget.ScrollView} and
|
|
{@link android.widget.HorizontalScrollView} do all this for you do all of this for you if you nest your layout within them.</p>
|
|
|
|
<h2 id = "scroll">Implement Touch-Based Scrolling</h2>
|
|
|
|
|
|
<p>This snippet illustrates the basics of using a scroller. It uses a
|
|
{@link android.view.GestureDetector}, and overrides the
|
|
{@link android.view.GestureDetector.SimpleOnGestureListener} methods
|
|
{@link android.view.GestureDetector.OnGestureListener#onDown onDown()} and
|
|
{@link android.view.GestureDetector.OnGestureListener#onFling onFling()}. It also
|
|
overrides {@link android.view.GestureDetector.OnGestureListener#onScroll onScroll()}
|
|
to return {@code false} since you don't need to animate a scroll.</p>
|
|
|
|
|
|
<p>It's common to use scrollers in conjunction with a fling gesture, but they
|
|
can be used in pretty much any context where you want the UI to display
|
|
scrolling in response to a touch event. For example, you could override {@link
|
|
android.view.View#onTouchEvent onTouchEvent()} to process touch events directly,
|
|
and produce a scrolling effect in response to those touch events.</p>
|
|
|
|
<pre>
|
|
private OverScroller mScroller = new OverScroller(context);
|
|
|
|
private GestureDetector.SimpleOnGestureListener mGestureListener
|
|
= new GestureDetector.SimpleOnGestureListener() {
|
|
@Override
|
|
public boolean onDown(MotionEvent e) {
|
|
// Abort any active scroll animations and invalidate.
|
|
mScroller.forceFinished(true);
|
|
// There is also a compatibility version:
|
|
// ViewCompat.postInvalidateOnAnimation
|
|
postInvalidateOnAnimation();
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean onScroll(MotionEvent e1, MotionEvent e2,
|
|
float distanceX, float distanceY) {
|
|
// You don't use a scroller in onScroll because you don't need to animate
|
|
// a scroll. The scroll occurs instantly in response to touch feedback.
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean onFling(MotionEvent e1, MotionEvent e2,
|
|
float velocityX, float velocityY) {
|
|
// Before flinging, abort the current animation.
|
|
mScroller.forceFinished(true);
|
|
// Begin the scroll animation
|
|
mScroller.fling(
|
|
// Current scroll position
|
|
startX,
|
|
startY,
|
|
// Velocities, negated for natural touch response
|
|
(int) -velocityX,
|
|
(int) -velocityY,
|
|
// Minimum and maximum scroll positions. The minimum scroll
|
|
// position is generally zero and the maximum scroll position
|
|
// is generally the content size less the screen size. So if the
|
|
// content width is 1000 pixels and the screen width is 200
|
|
// pixels, the maximum scroll offset should be 800 pixels.
|
|
minX, maxX,
|
|
minY, maxY,
|
|
// The maximum overscroll bounds. This is useful when using
|
|
// the EdgeEffect class to draw overscroll "glow" overlays.
|
|
mContentRect.width() / 2,
|
|
mContentRect.height() / 2);
|
|
// Invalidate to trigger computeScroll()
|
|
postInvalidateOnAnimation();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
@Override
|
|
public void computeScroll() {
|
|
super.computeScroll();
|
|
|
|
// Compute the current scroll offsets. If this returns true, then the
|
|
// scroll has not yet finished.
|
|
if (mScroller.computeScrollOffset()) {
|
|
int currX = mScroller.getCurrX();
|
|
int currY = mScroller.getCurrY();
|
|
|
|
// Actually render the scrolled viewport, or actually scroll the
|
|
// view using View.scrollTo.
|
|
|
|
// If currX or currY are outside the bounds, render the overscroll
|
|
// glow using EdgeEffect.
|
|
|
|
} else {
|
|
// The scroll has finished.
|
|
}
|
|
}</pre>
|
|
|
|
<p>For another example of scroller usage, see the <a href="http://github.com/android/platform_frameworks_support/blob/master/v4/java/android/support/v4/view/ViewPager.java">source code</a> for the
|
|
{@link android.support.v4.view.ViewPager} class.</p>
|