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. http://blog.csdn.net/sergeycao
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:
@Override
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}
Touch events by themselves are not particularly useful. Modern touch UIs define interactions in terms of gestures such as tapping, pulling, pushing, flinging, and zooming. To convert raw touch events into gestures, Android provides
GestureDetector
.
Construct a GestureDetector
by passing in an instance of a class that implements
GestureDetector.OnGestureListener
. If you only want to process a few gestures, you can extend
GestureDetector.SimpleOnGestureListener
instead of implementing the
GestureDetector.OnGestureListener
interface. For instance, this code creates a class that extends
GestureDetector.SimpleOnGestureListener
and overrides
onDown(MotionEvent)
.
class mListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onDown(MotionEvent e) {
return true;
}
}
mDetector = new GestureDetector(PieChart.this.getContext(), new mListener());
Whether or not you use GestureDetector.SimpleOnGestureListener
, you must always implement an
onDown()
method that returns true
. This step is necessary because all gestures begin with an
onDown()
message. If you return false
from
onDown()
, as GestureDetector.SimpleOnGestureListener
does, the system assumes that you want to ignore the rest of the gesture, and the other methods of
GestureDetector.OnGestureListener
never get called. The only time you should return
false
from onDown()
is if you truly want to ignore an entire gesture. Once you've implemented
GestureDetector.OnGestureListener
and created an instance of
GestureDetector
, you can use your GestureDetector
to interpret the touch events you receive in
onTouchEvent()
.
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean result = mDetector.onTouchEvent(event);
if (!result) {
if (event.getAction() == MotionEvent.ACTION_UP) {
stopScrolling();
result = true;
}
}
return result;
}
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
.
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
mScroller.fling(currentX, currentY, velocityX / SCALE, velocityY / SCALE, minX, minY, maxX, maxY);
postInvalidate();
}
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.
The call to fling()
sets up the physics model for the fling gesture. Afterwards, you need to update the
Scroller
by calling Scroller.computeScrollOffset()
at regular intervals.
computeScrollOffset()
updates the Scroller
object's internal state by reading the current time and using the physics model to calculate the x and y position at that time. Call
getCurrX()
and getCurrY()
to retrieve these values.
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.
if (!mScroller.isFinished()) {
mScroller.computeScrollOffset();
setPieRotation(mScroller.getCurrY());
}
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: ValueAnimator
isn't available prior to API level 11, but you can still use it 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.
mScroller = new Scroller(getContext(), null, true);
mScrollAnimator = ValueAnimator.ofFloat(0,1);
mScrollAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
if (!mScroller.isFinished()) {
mScroller.computeScrollOffset();
setPieRotation(mScroller.getCurrY());
} else {
mScrollAnimator.cancel();
onScrollFinished();
}
}
});
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.
mAutoCenterAnimator = ObjectAnimator.ofInt(PieChart.this, "PieRotation", 0);
mAutoCenterAnimator.setIntValues(targetAngle);
mAutoCenterAnimator.setDuration(AUTOCENTER_ANIM_DURATION);
mAutoCenterAnimator.start();
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:
animate().rotation(targetAngle).setDuration(ANIM_DURATION).start();
分享到:
相关推荐
Making the Good Life Last.pdf Four Keys to Sustainable Living
Wiley - Grid Computing Making the Global Infrastructure a Reality中国科技大学教材
unit 4 making the news重点词汇详解.docx
帮助你如何做好科研,而且涉及到时间管理、项目管理、人力资源管理、沟通协调、发表论文、申请项目、与人合作、和同行net-working、扩大影响力等等。
It also explains how you can extend it with custom events, making the application truly interactive. Chapter 3, Animations, deals with ArtistAnimation, FuncAnimation, and timers to make animations ...
一部很好的学术发展指导书,好好阅读,大有裨益!!!!!!
unit 4 making the news grammar.docx
If you find this software useful then please consider making a small donation towards the ongoing development costs. Website hosting costs money, as do compilers and development tools.
Making up the Mind How the Brain Creates Our Mental World
高中英语必修五Unit Making the newsPPT课件.pptx
Getting Started with p5.js Making Interactive Graphics in JavaScript and Processing 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除
TOGAF - making the bussiness case
英语:unit4 making the news单元同步测试.docx
unit 4 making the news倒装讲解及练习.docx
unit 4 making the news- language points学案.docx
unit 4 making the news 新人教版必修5.docx
Getting Started with p5.js Making Interactive Graphics in JavaScript and Processing 英文无水印pdf pdf所有页面使用FoxitReader和PDF-XChangeViewer测试都可以打开 本资源转载自网络,如有侵权,请联系上传...
新课程高中英语必修 unit Making the NewsPPT学习教案.pptx
It presents both the theory behind decision making models and algorithms and a collection of example applications that range from speech recognition to aircraft collision avoidance. Focusing on two ...
车牌识别matlab源程序 ...% segments were found, it attempts to recall the function, making the % separation between the already found segments clearer (by cleaning the % bits which are there.