Written in the previous words: This chapter is very valuable, want to enhance the knowledge of Android must read. Other aspects of Ascension can also be achieved without being an android.
Original address: http://android.xsoftlab.net/training/custom-views/making-interactive.html
The drawing of the UI is only part of the custom view. You also need to enable view to respond to user input events in a way that is close to the real-world feedback. Objects in the virtual world should always act in the way that objects in the real world behave. For example, images should not suddenly appear or disappear from somewhere, because real-world images are always moved from one place to another.
Users should also be aware of some subtle sensations on the UI interface. The best feedback is to mimic the subtle behavior of the real world. For a chestnut, when the user quickly slides the UI object, it should feel the delayed friction at the beginning and should continue to slide after the slide.
This lesson will show you how to add these real-world behaviors to your custom view using Android's framework features.
Handling input gestures
Similar to other UI frameworks, Android also supports the input event model. The user's behavior is converted to an event that triggers a callback, and you can override these callback methods to determine how to respond to these events. The most common input event in Android is touch, which triggers ontouchevent (android.view.MotionEvent). To handle some events by overriding this method:
@Override publicbooleanonTouchEvent(MotionEvent event) { returnsuper.onTouchEvent(event); }
Touching the event itself is not particularly useful. The touch UI defines interactive gestures such as double-click, drop-down, push-up, quick swipe, zoom, and so on. To convert the original touch events to gestures, Android provides gesturedetector.
Constructing the Gesturedetector requires passing a Gesturedetector.ongesturelistener implementation class as a parameter. If you just need to handle a few gestures, you can inherit Gesturedetector.simpleongesturelistener. The following code inherits this interface and overrides its Ondown (motionevent) method.
class mListener extends GestureDetector.SimpleOnGestureListener { @Override publicbooleanonDown(MotionEvent e) { returntrue; new GestureDetector(PieChart.thisnew mListener());
Whether you use the Gesturedetector.simpleongesturelistener interface or not, you need to implement a Ondown () method that returns true. This step is necessary because all gestures start with the Ondown () method. If you return False in the Ondown () method, then the system will assume that you want to ignore this event and that other related methods will not be called. If you really want to ignore the entire gesture event, then returning false in the Ondown () method is the only way. Once the Gesturedetector.ongesturelistener interface is implemented and an instance of Gesturedetector is created, the Gesturedetector object can be used with the ontouchevent () To interact with the touch events received in the
@OverridepublicbooleanonTouchEvent(MotionEvent event) { boolean result = mDetector.onTouchEvent(event); if (!result) { if (event.getAction() == MotionEvent.ACTION_UP) { stopScrolling(); true; } } return result;}
When passed an unrecognized gesture to the Ontouchevent () method, it returns false so that you can run the custom gesture recognition code.
Create a physical analog gesture
Gestures are a powerful way to control touchscreen devices, and they can be counterintuitive and hard to remember unless they provide a physical simulation effect. A good example is a fast swipe gesture: When a user slides a finger quickly on the screen, the finger suddenly leaves the screen, triggering the gesture. If the UI continues to slide in the same direction and slowly slows down, it will create a feeling for the user: as if operating a flywheel.
In any case, the feeling of simulating a flywheel is not worthless. In order to correctly simulate this feeling, a lot of physical and mathematical operations are required. Fortunately, Android provides an auxiliary class for this. Scroller is an auxiliary class designed to handle this kind of flywheel feeling gesture.
In order to start the slide, fling () needs to be called with an initial velocity value and other related speed parameters. For the speed value, you can get it by gesturedetector calculation.
@OverridepublicbooleanonFlingfloatfloat velocityY) { mScroller.fling(currentX, currentY, velocityX / SCALE, velocityY / SCALE, minX, minY, maxX, maxY); postInvalidate();}
Note: Although the speed value calculated by Gesturedetector is physically accurate, many developers feel that using this value to start sliding is too fast. Typically, a factor is taken between 4 and 8 to reduce the x and Y.
First Call Fling () to set the physical model for the swipe gesture. You then need to periodically call Scroller.computescrolloffset () to update the scroller. Computescrolloffset () updates the internal state of the Scroller object by reading the current time and using the physical model to calculate the position of x and Y. These values are received by calling Getcurrx () and Getcurry ().
Many view passes the position value of x, y of the Scroller object directly to Scrollto (). The pie chart example is a little different here: it uses the position of the current sliding y to set the rotation angle of the pie:
if (!mScroller.isFinished()) { mScroller.computeScrollOffset(); setPieRotation(mScroller.getCurrY());}
Scroller will calculate the slide position for you, but it will not automatically apply these values to your view. To make the view's sliding effect smoother, it's up to you to get and apply the values. There are two ways to achieve this:
- Postinvalidate () is called after fling () so that the interface can be redrawn. This method needs to be called in the OnDraw () method after each sliding offset has changed.
- Set Valueanimator for the slide animation, call Addupdatelistener () to add a listener to handle the update of the animation.
The second scenario is used in the pie chart example. This technique is slightly more complex to set up, but its working process is closer to the animation system and does not request unnecessary updates. The disadvantage is that Valueanimator does not work before API 11, so this technology is not available until Android 3.0.
Note: Valueanimator is not available until API 11, but you can still use it before API 11. You only need to make sure that the current API level is checked at run time and that you do not call the view animation when the level is below 11.
Mscroller =NewScroller (GetContext (),NULL,true); Mscrollanimator = Valueanimator.offloat (0,1); Mscrollanimator.addupdatelistener (NewValueanimator.animatorupdatelistener () {@Override Public void onanimationupdate(Valueanimator valueanimator) {if(!mscroller.isfinished ()) {Mscroller.computescrolloffset (); Setpierotation (Mscroller.getcurry ()); }Else{Mscrollanimator.cancel (); Onscrollfinished (); } } });
Make the sliding process smoother
The user does not want the transitions between states to occur in the Dayton. As a result, the fade of the UI element replaces the flashing and disappearing. The smooth transition of the action replaces the sudden start and stop. The property animation framework that appears in Android 3.0 makes smooth transitions easier.
Changes to the properties of each property affect the appearance of the view, so do not change their properties directly. Instead, you can use Valueanimator to make changes. In the following example, modifying the currently selected pie chart will cause the entire pie to rotate, so the selected point appears to be in the middle of the pie chart. Valueanimator changed the rotation time by hundreds of milliseconds.
mAutoCenterAnimator = ObjectAnimator.ofInt(PieChart.this"PieRotation"0);mAutoCenterAnimator.setIntValues(targetAngle);mAutoCenterAnimator.setDuration(AUTOCENTER_ANIM_DURATION);mAutoCenterAnimator.start();
This is easier if you want to change the underlying properties of the view because the view has a built-in view property animation frame Viewpropertyanimator, which is designed to work with multiple properties at once, such as:
animate().rotation(targetAngle).setDuration(ANIM_DURATION).start();
Android Official Development Document Training Series Course Chinese: Create a custom View view interaction