Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Case Analysis of event system of Android View

2025-02-25 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

Most people do not understand the knowledge points of this "case Analysis of Android View event system" article, so the editor summarizes the following content, detailed content, clear steps, and has a certain reference value. I hope you can get something after reading this article. Let's take a look at this "case Analysis of Android View event system" article.

What is View? What is ViewGroup?

View is the base class for all controls in Android, whether it's Button, ListView, or RelativeLayout, whose base class is View. View is an abstraction of controls at the interface layer, representing a control.

What is ViewGroup? literally, ViewGroup should refer to a group of controls, that is, ViewGroup can contain many controls. ViewGroup inherits from View, so View itself can be a single control or a set of controls made up of multiple controls. This forms the View tree.

Second, the location of View

The location of View is determined by its four vertices, top (upper left ordinate), left (upper left Abscissa), bottom (lower right ordinate), and right (lower right Abscissa), all of which are relative to the parent container.

In Android, the positive directions of the X and Y axes are right and down, respectively.

According to the four vertices and the coordinate system of AndroidView, we can easily get the relationship between the width and height of View and its coordinates:

Width=right-left

Height=bottom-top

So how do you get these four vertices?

Left=getLeft ()

Right=getRight ()

Top=getTop ()

Bottom=getBottom ()

Starting with Android3.0, View has added xmemy translation X and translationY. Where x and y are the coordinates of the upper-left corner of the view (relative coordinate system), and translationX and translationY are the offsets of the upper-left View relative to the parent container.

X=left+translationX

Y=top+translationY

It should be noted that during the translation of View, top and left represent the position information of the original upper left corner, and their values will not change, but the changes will be x, y, translationX and translationY.

Third, the touch event 1.MotionEvent of View

Among a series of events that occur after a finger touches the screen, typical events are:

ACTION_DOWN-- 's fingers just touched the screen.

ACTION_MOVE-- 's fingers move on the screen.

ACTION_DOWN-- released his finger from the screen.

Generally speaking, we can divide the behavior of a finger touching the screen into two situations:

Click on the screen and release. The event sequence is DOWN- > UP.

Click on the screen to slide for a period of time and release it. The event sequence is DOWN- > MOVE- >. -> MOVE- > UP

2.TouchSlop

TouchSlop is the minimum distance at which the system can recognize sliding, which is a device-related system constant. It's not hard to know what it means. When your fingers slide less than this distance on the screen, the system doesn't think you're sliding.

Get this system constant through the ViewConfiguration.get (getContext ()) .getScaledTouchSlop () method.

3.VelocityTracker

Speed tracking, used to track the speed of the finger during sliding, including the speed in the horizontal and vertical directions.

Specific usage:

Track the speed of the current click event in the onTouchEvent method of View.

VelocityTracker velocityTracker = VelocityTracker.obtain (); velocityTracker.addMovement (event); / / then when we want to know the current sliding speed / / calculate the speed before we get the speed, the parameter interval is msvelocityTracker.computeCurrentVelocity (1000); / / get the speed int xVelocity = (int) velocityTracker.getXVelocity (); int yVelocity= (int) velocityTracker.getYVelocity ()

It should be noted that the speed calculated here is related to the time interval, and the calculation formula is as follows:

Speed = (end position-start position) / interval

When calculating speed, it is the number of pixels in which the finger slides horizontally or vertically over a certain time interval, such as

100 pixels / 1000ms, where the speed value is 100.

Of course, when you don't need to use it, you need to call the clear method to reset and reclaim memory.

VelocityTracker.clear ()

VelocityTracker.recycle ()

4.GestureDetector

Gesture detection, which is used to assist in detecting the user's click, slide, long press, double click and other behaviors. If only listening slides related suggestions are implemented in onToucheEvent, if you need to listen double-click, use GestureDetector.

5.Scroller

Elastic sliding object, which is used to realize the elastic sliding of View. The scrollTo/scrollBy of View is completed instantly. Scroller is used in conjunction with View's computeScroll method to achieve the effect of elastic sliding.

The typical code is universal.

/ * * smooth scrolling * @ param dx lateral displacement * @ param dy * / private void smoothScrollBy (int dx, int dy) {/ / horizontal sliding mScroller.startScroll (getScrollX (), 0meme dxPower0500); invalidate ();} @ Overridepublic void computeScroll () {if (mScroller.computeScrollOffset ()) {scrollTo (mScroller.getCurrX (), mScroller.getCurrY ()); postInvalidate ();}} fourth, sliding of View

Several ways to implement View sliding:

The sliding mode of View is suitable for the scene to use ScrollTo/ScrollBy can only change the content of View, can not change the position of View itself is suitable for the sliding of view content through animation to achieve the translation effect of View only operate on the image, can not change the position parameters of View is suitable for non-interactive View and to achieve complex animation effects. Use attribute animation to realize the translation effect of View to change the position parameters of View, which can be applied to interactive View in response to events such as touch, and adapt to Android3.0 to change the LayoutParams of View, so that View relayout can realize sliding to change the position parameters of View, and can respond to events such as touch. It is suitable for interactive View, and the use is slightly complex.

Previously mentioned elastic sliding object Scroll, in fact, there are more than one way to achieve elastic sliding, their common idea is to divide a large slide into several small slides and require it to be completed in a certain period of time. The specific ways to achieve elastic sliding are as follows:

Implemented through Scroll

Through animation

Use delay strategy

1) use Scroll

Using Scroll to realize elastic sliding needs to cooperate with the computeScroll method of View. To put it simply, it is to redraw many times, each redrawing has a certain time interval, through this time interval Scroller can get the current sliding position of View, and then realize the sliding by ScrollTo method.

The specific implementation method is to call the invalidate method in the smooth sliding method implemented by ourselves, which will lead to View redrawing, and because the computeScroll method will be called in the draw method of View, while in the computeScroll method, we implement the scrollTo method to achieve sliding, and then call postInvalidate for the second redrawing, and then call the draw method in View, and then call the computeScroll method, repeatedly until the whole sliding process is completed.

2) through animation

Animation itself is a gradual process, which can achieve elastic sliding very well.

3) use delay strategy

Using a delay strategy to complete sliding, the core idea is to achieve a gradual effect by sending a series of delayed messages. The specific implementation can use the postDelayed method of Handler or View, or sleep hibernation. For postDelayed methods, you can use it to delay sending a message, and then scroll the View in the message. If such messages are sent one after another, the elastic sliding object can be achieved.

The sleep method, on the other hand, can be achieved by constantly sliding View and sleep in the while loop.

5. Event distribution mechanism of View

Distribution object: MotionEvent, the so-called event distribution is actually the distribution process of the MotionEvent event, that is, the event needs to be passed to a specific View for processing. To complete this process, three important methods are needed: dispatchTouchEvent, onInterceptTouchEvent and onTouchEvent.

Public boolean dispatchTouchEvent (MotionEvent ev)

Used for event distribution, the returned result is affected by the onTouchEvent of the current View and the dispatchTouchEvent method of the subordinate View, indicating whether the current event is consumed.

Public boolean onInterceptTouchEvent (MotionEvent ev)

Called inside the dispatchTouchEvent method to determine whether to intercept a certain time, if the current View intercepts an event, then this method will not be called again in the same event sequence.

Public boolean onTouchEvent (MotionEvent event)

Called in the dispatchTouchEvent method, which is used to process click events. The returned result indicates whether the event is consumed. If not, the current View cannot receive the event again in the same event sequence.

Based on the above method, let's briefly analyze the process of event distribution.

From the above flowchart, it is not difficult to find that when MotionEvent is intercepted by a View, the priority of onTouchListener is higher than that of onTouchEvent, while the priority of commonly used onClickListener is the lowest. That is, in onTouch- > onTouchEvent- > onClick.

Several important conclusions:

In event distribution throughout the View tree, once a View starts processing events, but it does not consume ACTION_DOWN events (onTOuchEvent returns false), other events in the same event sequence are not handed over to it for processing, but are handed back to its parent element for processing, that is, the onTouchEvent of the parent element is called.

If a View consumes ACTION_DOWN but does not consume other events in the event sequence, the click event will disappear, and the onTouchEvent of the parent element will not be called, and the current View can continue to receive subsequent events, and eventually these missing click events will be passed to the Activity for processing.

ViewGroup does not intercept any events by default

View does not have an onInterceptTouchEvent method, so once a click event is passed to it, you can call its onTouchEvent method.

View's onTouchEvent consumes events by default, unless it is unclickable (clickable and longClickable are false)

The event delivery process is from outside to inside, that is, the event is always passed to the parent element, and then distributed to the child View by the parent element. The requestDisallowInterceptTouchEvent method can interfere with the distribution process in the parent element (except ACTION_DOWN).

6. The problem of sliding conflict of View the common sliding conflict of View can be divided into three types:

1. The direction of external sliding and internal sliding are inconsistent.

two。 The external sliding direction is the same as the internal sliding direction.

3. The nesting of the above two cases

For the first case, a good example is the use of ViewPager and Fragment nesting to make up the page sliding effect, while a ListView is nested within Fragment. It is well known that the sliding direction of ViewPager is horizontal, while that of ListView is vertical, which is consistent with the first case. Of course, ViewPager handles this kind of sliding conflict internally, so you don't have to think about it when using ViewPager. If we are using ScrollView, we have to deal with this sliding conflict manually.

For the second case, both the inner and outer layers need to slide up and down or left and right. A common example can be given, namely ViewPager and NavigationDrawer. Both are horizontal slides. Of course, in the actual use, you will find that there is no sliding conflict, or the previous reason, ViewPager handled this kind of sliding conflict internally.

The third case is the integration of the first two examples.

Rules for handling sliding conflicts

How to solve the sliding conflict, which needs to use the event distribution mechanism mentioned earlier, its core idea is to judge which View will intercept the event according to the characteristics of the actual event (down position, horizontal sliding distance, vertical sliding distance, etc.). For the first case, you can simply determine whether to slide horizontally or vertically to determine which View will intercept the event. (it can be judged by the distance difference or speed difference in the horizontal and vertical directions), while in the second case, it can be distinguished according to the position of the down.

The solution of sliding conflict

External interception-that is, the click event is first intercepted by the parent container. If the parent container needs this event, it will be intercepted. If it is not needed, it will not be intercepted. The onInterceptTouchEvent method of the parent container needs to be overridden. In the onInterceptTouchEvent method, first of all, the ACTION_DOWN event, the parent container must return false, that is, the ACTION_DOWN event must not be intercepted, because once the parent container intercepts the ACTION_DOWN, the subsequent ACTION_MOVE/ACTION_UP will be directly handed over to the parent container for processing; the second is ACTION_MOVE, which decides whether to intercept according to the requirements; finally, the ACTION_UP event, where false must be returned, does not make much sense here.

Internal interception-all events are passed to the child element, which is consumed if the child element is needed, and left to the parent element if it is not needed, which requires the child element to cooperate with the requestDisallowInterceptTouchEvent method to work properly; the parent element needs to intercept events other than ACTION_DOWN by default, so that when the element calls the parent.requestDisallowInterceptTouchEvent (false) method, the parent element can continue to intercept the desired events. (the ACTION_DOWN event is not affected by the requestDisallowInterceptTouchEvent method, so once the parent element intercepts the ACTION_DOWN event, none of the elements can be passed to the child element)

The normal form of the two interception methods (pseudo-code form):

External interception: only the onInterceptTouchEvent method of the parent container needs to be overridden

Private int mLastXIntercepet=0; private int mLastYIntercepet=0; @ Override public boolean onInterceptTouchEvent (MotionEvent ev) {boolean intercepted=false; int x = (int) ev.getX (); int y = (int) ev.getY (); switch (ev.getAction ()) {case MotionEvent.ACTION_DOWN: intercepted=false; break Case MotionEvent.ACTION_MOVE: if (the parent container needs the current click event) {intercepted=true;} else {intercepted=false;} break; case MotionEvent.ACTION_UP: intercepted=false; break Default: break;} mLastXIntercepet=x; mLastYIntercepet=y; return intercepted;}

Internal interception: the dispatchTouchEvent method of the child element and the onInterceptTouchEvent method of the parent container need to be overridden.

The dispatchTouchEvent method of the child element

/ / record the last sliding coordinates private int mLastX=0; private int mLastY=0; @ Override public boolean dispatchTouchEvent (MotionEvent ev) {int x = (int) ev.getX (); int y = (int) ev.getY (); switch (ev.getAction ()) {case MotionEvent.ACTION_DOWN: getParent () .requestDisallowInterceptTouchEvent (true); break Case MotionEvent.ACTION_MOVE: int deltaX=x-mLastX; int deltaY=y-mLastY; if (parent container needs this kind of click event) {getParent () .requestDisallowInterceptTouchEvent (false);} break; case MotionEvent.ACTION_UP: break Default: break;} mLastX=x; mLastY=y; return super.dispatchTouchEvent (ev);}

OnInterceptTouchEvent of the parent container:

@ Override public boolean onInterceptTouchEvent (MotionEvent ev) {int x = (int) ev.getX (); int y = (int) ev.getY (); int action=ev.getAction (); if (action==MotionEvent.ACTION_DOWN) return false; else return true } the above is the content of this article on "case Analysis of Android View event system". I believe we all have some understanding. I hope the content shared by the editor will be helpful to you. If you want to know more about the relevant knowledge, please follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report