Making the View Interactive

Drawing a UI is only one part of creating a custom view. You also need to make your view respond
to user input in a
way that closely resembles the real-world action you're mimicking. Objects should always act in the
same way that real
objects do. For example, images should not immediately pop out of existence and reappear somewhere
else, because objects
in the real world don't do that. Instead, images should move from one place to another.

Users also sense subtle behavior or feel in an interface, and react best to subtleties that
mimic the real world.
For example, when users fling a UI object, they should sense friction at the beginning that delays
the motion, and then
at the end sense momentum that carries the motion beyond the fling.

This lesson demonstrates how to use features of the Android framework to add these real-world
behaviors to your
custom view.

Handle Input Gestures

Like many other UI frameworks, Android supports an input event model. User actions are turned
into events that
trigger callbacks, and you can override the callbacks to customize how your application responds
to the user. The
most common input event in the Android system is touch, which triggers onTouchEvent(android.view.MotionEvent). Override this method to handle the
event:

When you pass onTouchEvent() a touch event that
it doesn't
recognize as part of a gesture, it returns false. You can then run your own custom
gesture-detection
code.

Create Physically Plausible Motion

Gestures are a powerful way to control touchscreen devices, but they can be counterintuitive and
difficult to
remember unless they produce physically plausible results. A good example of this is the fling
gesture, where the
user quickly moves a finger across the screen and then lifts it. This gesture makes sense if the UI
responds by moving
quickly in the direction of the fling, then slowing down, as if the user had pushed on a
flywheel and set it
spinning.

However, simulating the feel of a flywheel isn't trivial. A lot of physics and math are required
to get a flywheel
model working correctly. Fortunately, Android provides helper classes to simulate this and other
behaviors. The
Scroller class is the basis for handling flywheel-style fling
gestures.

To start a fling, call fling() with the starting velocity
and the minimum and
maximum x and y values of the fling. For the velocity value, you can use the value computed for
you by GestureDetector.

Note: Although the velocity calculated by
GestureDetector is physically accurate,
many developers feel
that using this value makes the fling animation too fast. It's common to divide the x and y
velocity by a factor of
4 to 8.

Most views pass the Scroller object's x and y position directly to
scrollTo(). The PieChart example is a little different: it
uses the current scroll
y position to set the rotational angle of the chart.

Kotlin

Java

The Scroller class computes scroll positions for you, but it does
not automatically
apply those positions to your view. It's your responsibility to make sure you get and apply new
coordinates often
enough to make the scrolling animation look smooth. There are two ways to do this:

The PieChart example uses the second approach. This technique is slightly more complex to set up, but
it works more
closely with the animation system and doesn't require potentially unnecessary view
invalidation. The drawback is that ValueAnimator
is not available prior to API level 11, so this technique cannot be used
on devices running Android versions lower than 3.0.

Note: You can use ValueAnimator in
applications that
target lower API levels. You just need to make sure to check the current API level
at runtime, and omit the calls to the view animation system if the current level is less than 11.

Make Your Transitions Smooth

Users expect a modern UI to transition smoothly between states. UI elements fade in and out
instead of appearing and
disappearing. Motions begin and end smoothly instead of starting and stopping abruptly. The
Android property animation
framework, introduced in
Android 3.0, makes smooth transitions easy.

To use the animation system, whenever a property changes that will affect your view's appearance,
do not change the
property directly. Instead, use ValueAnimator to make the change. In
the following
example, modifying the
currently selected pie slice in PieChart causes the entire chart to rotate so that the selection
pointer is centered
in the selected slice. ValueAnimator changes the rotation over a
period of several
hundred milliseconds,
rather than immediately setting the new rotation value.

If the value you want to change is one of the base View properties, doing
the animation
is even easier,
because Views have a built-in ViewPropertyAnimator that is optimized for
simultaneous animation
of multiple properties. For example: