Introduction to view Basics (II.)

Source: Internet
Author: User
Tags gety

Introduction to view Basics

Slide of view

  • View sliding can be achieved in three ways:

    1. The Scrollto and Scrollby methods provided by the view itself
    2. Apply a panning effect to an animation to achieve
    3. By changing the layoutparams of the view to make the view re-layout to achieve

      • Scrollto/scrollby
        ①. By looking at the source of the view, we can see that the Scrollby method is actually called the Scrollto method.

        scrollTo方法是基于所传递参数的绝对位置滑动 而scrollBy是根据所传递参数基于当前未知的滑动通过源码可知 这两个方法只能改变view内容的位置 而不能改变view在布局中的位置

        ②. Using animations

            如果使用动画来进行view的滑动 需要注意的是 动画是对view的影像所做的操作 并没有真正改变view的参数 如果希望动画过后的状态还可以保留的话 需要将fillAfter属性设置为true 否则动画结束之后影像会消失    使用动画对view影像进行操作的话 会带来一个严重的问题 那就是view的影像无法响应onClick事件    而view的真实位置依然可以响应onClick事件    针对以上问题 解决方案为 我们可以在新位置蔚县创建一个和目标view一摸一样的view 连点击事件也相同    在view完成平移动画之后 将目标view隐藏 将我们预先创建好的view显示出来

        ③. Changing layout parameters
        By changing the margin property of the target Wiew, the view can be shifted or we can set a view with a width of 0 to the target view to change the width of the view when the shift is needed, which can naturally achieve the purpose of moving the target view.

        Three different ways to compare

        scrollTo/scrollBy    操作简单 适合对view内容的滑动    是view提供的原生的实现滑动效果并且不影响内部点击事件的方法 但他只能滑动view内容 不能滑动view本身动画    操作简单 主要适用于对外界没有交互的view和实现复杂的动画效果改变布局参数    操作略微复杂 适合于有交互的view
      • Elastic sliding

        Scroller Elastic Sliding objects
        To achieve the elastic sliding of the view when we use the view's Scrollto and Scrollby operation, the view slide is an instantaneous experience, so we need to use the Scroller object to implement the view's elastic sliding operation. Scroller itself cannot realize the elastic sliding of view needs to be used with the Computescroll method of view

        The code is as follows

            /** * Custom Slide View * Note that the way the time is called or the Scrollto method of the view slides just the view content does not change the view's actual location * /     Public  class scrollerview extends View{        PrivateContext Mcontext;//Sliding total time default to 1000ms can be set        Private intMduration = +;//Construct a Scroller object        PrivateScroller Mscroller =NewScroller (Mcontext); Public Scrollerview(Context context) {Super(context);        Mcontext = context; }/** * Slow slide to a position * @param destx The x-coordinate to slide to the position * @param desty The y-coordinate to slide to the position */         Public void Smoothscrollto(intDESTX,intDesty) {//Get the current location of the view            intSCROLLX = Getscrollx ();//Calculate the distance that the view needs to slide            intDeltaX = DESTX-SCROLLX;intscrolly = getscrolly ();intDeltaY = desty-scrolly;//slide toward DESTX within the specified time            //By reading the source code of the method we can find that in this method only the data we set is recorded and there is no substantive sliding of the viewMscroller.startscroll (scrollx,scrolly,deltax,deltay,mduration);//Focus here calling this method can cause the view to redraw when the view redraw calls the draw method in the draw method and calls the Computescroll method            The //computescroll method is an empty implementation in view where we rewrite itInvalidate (); }/** * View method is called in the draw method of view, but in view is an empty implementation of the specific code needs our own to supplement * * scroller need to cooperate with this method in order to achieve elastic sliding specific reasons are as follows * We call the Invalidate method when we start sliding, this method causes the view to redraw the view redraw when the draw method calls the Computescroll method * because we've rewritten it and called our code here here we're going to M Scroller Request view current location by Scrollto method to set it * then call postinvalidate method again cause view redraw and so on * * /        @Override         Public void Computescroll() {//The method of judging the condition by reading the source to determine its total execution time and the current time to decide whether the slide is over if it has not ended            //Returns True while calculating the position where the view should currently slide when the slide is not finished we go to the position where the view should currently slide            //Use the Scrollto method to set it and invoke the Postinvalidate method to make the view redraw            if(Mscroller.computescrolloffset ())                {ScrollTo (Mscroller.getcurrx (), Mscroller.getcurry ());            Postinvalidate (); }        }/** * Set the total time of the view elastic slide * @param duration View Elastic sliding time * *         Public void setmduration(intDuration) {mduration = duration; }    }
      • Animation
        Animation can easily achieve the effect of elastic sliding, which is similar to the Scroller object in the animation we can set the Addupdatelistener
        Plus some other things we want to do

      • Using the delay policy

        The core point of using the delay strategy is still the implementation of the Scrollto method delay using the view can be achieved through handler or view postdelay thread sleep, etc.

Event distribution mechanism for view

  • Click the Pass rule for the event
    The delivery of the Click event is actually the distribution process of the Motionevent event. The distribution process of the event is mainly done by the following three methods

    public boolean dispatchTouchEvent(MotionEvent ev)该方法用来进行事件的分发 如果事件能够传递到当前view 那么此方法 一定会被调用返回结果受当前view的onTouchEvent方法和下级view的dispatchTouchEvent方法的影响 表示是否能消耗当前事件public boolean onInterceptTouchEvent(MotionEvent ev)该方法在dispatchTouchEvent方法内部调用 用来判断当前view是都拦截某个事件 如果当前view拦截了某个事件那么在同一事件序列中 此方法不会被再次调用 返回结果表示是否拦截当前事件public boolean onTouchEvent(MotionEvent ev)在dispatchTouchEvent方法中调用 用来处理点击事件 返回结果表示是否消耗当前事件 如果不消耗 则在同一事件序列中当前view无法再次接受到事件上述三个方法之间的关系可以用以下伪代码来表示    public boolean dispatchTouchEvent(MotionEvent ev){        boolean consume = false;        if(onInterceptTouchEvent(ev)){            consume = onTouchEvent(ev);        }else{            consume = child.dispatchTouchEvent(ev);        }        return consume;    }

    For a root VIEWGROUNP, a click event will be passed to him first, and then his dispatchtouchevent will be called if the
    The VIEWGROUNP Onintercepttouchevent method returns True to indicate that the VIEWGROUNP is intercepting the current event, so the current event
    will be handed over to VIEWGROUNP's Ontouchevent method to handle if this VIEWGROUNP's Onintercepttouchevent method returns false
    Indicates that this event is not intercepted so this event will be passed to VIEWGROUNP's child element to handle the Dispatchtouchevent method of the child element, which is called so repeatedly until the event is finally processed.

    When a view needs to handle an event, if he sets the Ontouchlistener then Ontouchlistener will be called First call Ontouchlistener
    The Ontouch method in this case the result of the event is to see the results of Ontouch return if Ontouch returns false then the Ontouchevent method of the view is called to handle the event when Ontouchevent handles the event If we set onclicklistener at this point, Onclicklistener will be called from here we can see that the Onclicklistener priority we often use is at the end of the event delivery mechanism.

    The priority levels of these methods are as follows
    Ontouchlistener–>ontouchevent–>onclicklistener

    When a click event is generated, his delivery process follows the following rules
    Activity–>window–>view
    Events are always passed to the activity activity before being passed to the window's last window and then distributed to the top view Top view when the event is received and followed
    Event distribution mechanism to distribute the event at this point if the end of view returns false in Ontouchevent then its parent container's Ontouchevent method will be called and so on if none of the elements handle the event Then the event will eventually be returned to the Ontouchevent method of activity handling activity.
    will be called this process is similar to the task in the daily life of the delegation process as superior delegated subordinates to handle subordinate delegation to the lower level to deal with if the subordinate can not handle the event then the event will eventually return to the superior to handle the

    About the event delivery mechanism here are some conclusions based on these conclusions, you can better understand the event delivery mechanism as shown below

    1. The same sequence of events refers to a series of events that occur from the moment the finger is lifted to the end of the screen and ends in the middle of the line. This sequence of events starts with a down event and contains an unequal number of move events in the middle of the up event

    2. Normally, an event sequence can only be intercepted and consumed by one view because once an element has intercepted this event, all events in the same sequence of events are handed over to that element for processing, so events in the same event sequence cannot be handed over to two view simultaneous processing but by special means A view, for example, forcibly passes an event that is supposed to be handled by ontouchevent to other view processing

    3. Once a view intercepts an event then the sequence of events can only be handled by him and its onintercepttouchevent will not be called again because all the events in this sequence are handled by him, so there's no need to ask him if he's intercepted.

    4. Once a view begins to process an event if he does not consume Action_down and returns false then the event will be re-handed to his parent element to process the parent element's ontouchevent will be recalled meaning that once the event is handed to a view to handle Then he's going to have to consume it at least to consume the action_down. Otherwise, the other events in the same event sequence will no longer be handed over to him. It's like the superior gives you a mission. You didn't take care of it in the first place, and then the mission didn't give you the same thing.

    5. If the view does not consume events other than Action_down, then the click event disappears and the Ontouchevent method of the parent element is not called and the current view can continue to accept subsequent events in the sequence of events Eventually these disappearing events will be given to the activity to deal with.

    6. VIEWGROUNP default does not intercept any events in the Android source VIEWGROUNP Onintercepttouchevent method default return to False

    7. View no Onintercepttouchevent method event once passed to him then his ontouchevent method will be called.

    8. The Ontouchevent method of view consumes events by default to return true unless his current state is not clickable (clickable and longclickable are false simultaneously) view longclickable default is False Clickable conditions such as a button of true TextView to False

    9. The Enable property of the view does not affect the default return value of Ontouchevent even if a view is currently in an unavailable state, his ontouchevent method will still return true to consume the event

    10. The onclick will occur if the current view is clickable and he receives the down and up events

    11. The event delivery process is performed by an extrovert, where the event is always first passed to the parent element and then distributed by the parent element to the child element by requestdisallowintercepttouchevent
      The Action_down method can intervene in a child element to interfere with the parent element's event distribution process to request that the parent element not intercept the event the method is invalid because reading the source indicates that the method will change
      A tag bit in the parent element when the event is Acion_down, this flag bit is reset, so the method is not valid for Action_down

The sliding conflict of view

  • Conflict scenarios

    1. External slide inconsistent with internal slide direction
    2. The external sliding direction is consistent with the internal sliding direction
    3. These two cases are nested
  • Processing rules

    1. For Scenario 1, when users swipe left and right, you need to let the outside view intercept event when users swipe up and down to let the internal view intercept event What we need to do is to judge the direction of the user's slide. In particular, we can judge the direction of the user's slide according to the distance difference between the user's horizontal sliding and vertical sliding.
    2. For the scenario, we cannot determine which view to swipe by the user's sliding direction, so for this type of sliding conflict we need to differentiate between the two types of sliding in the business, for example, when a state requires an external view to respond to a user's swipe A different state requires an internal view to respond to the user's swipe
    3. For Scenario 3, a single solution to this more complex sliding conflict is definitely not going to work, so we need to combine the top two scenarios and use specific scenarios to analyze them.
  • How to Solve

    1. For scenario 1, there are two methods of external interception and internal interception for specific solutions.
  • External interception method
    means that all click events are intercepted by the parent container (not including the down event) if the parent container needs this event to intercept if it is not necessary to intercept the external interception method, the Onintercepttouchevent method of overriding the parent container is required to make the corresponding judgment processing in the method. The general logic can
    According to the following pseudo code to derive

        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 MotionEvetn.ACTION_MOVE:                if(父容器需要该事件){                    intercepted = true;                }else{                    intercepted = false;                }                break;            case MotionEvent.ACTION_UP:                intercepted = false;                break;            default:                break;        }        mLastXIntercept = x;        mLastYIntercept = y;        return intercepted;    }

    The above code is the typical logic of the external interception method for different sliding conflict processing only need to modify the parent container to require the current event condition can be no other need to make changes in the above code Action_down event parent container must return false because once the parent container intercepts the event Then none of the events in the back can be passed to the child element. In the Action_move event we determine whether to intercept the event as needed here is the focus of the Code ACTION_UP event we also need to return false because if we intercept the event in the parent container's move event Then the subsequent events in the sequence of events are handed over to the parent container for processing we do not need to care about the up event if we do not summarize the Intercept move event in the parent container, the event should be left to the child element to deal with, but we are here to intercept the up event, and the parent container will handle it. The child element will not be able to receive the up event then the child element will not respond correctly to the Click event so here we need to return false for the Action_up event

    In summary, we just need to deal with the Action_move event. Action_down and Action_up Events we all just need to return false.

  • Internal interception method

    The internal interception method means that the parent container does not do any logical processing during the interception phase (not the parent element does not intercept, but the default is to intercept all event sub-elements except Action_down If an event is required. You need to get the event through the Requestdisallowintercepttouchevent () method) all the interception logic processing is given to the child element to process the child element, which is consumed directly if the child element does not need the event, it is handed to the parent container to handle Compared to the external intercept method, the method compares complex pseudo-code as shown below we need to rewrite the Dispatchtouchevent method of the child element

        public boolean dispatchTouchEvent(MotionEvent ev){        int x = (int) ev.getX();        int y = (int) ev.getY();        switch(MotionEvent.getAction()){            case MotionEvent.ACTION_DOWN:                requestDisallowInterceptTouchEvent(true);                break;            case MotionEvent.ACTION_MOVE:                if(子元素不需要该事件){                    requestDisallowInterceptTouchEvent(false);                }                break;            case MotionEvent.ACTION_UP:                break;            defalut:                break;        }        mLastX = x;        mLastY = y;        return super.dispatchTouchEvent(ev);    }

    The code above is a typical code for internal interception. When faced with a different sliding strategy, only need to modify the child elements in the method of the judgment condition can be other places do not need to make changes in addition to the child element needs to override the method outside the parent element also needs to make some processing needs to be blocked by default except Action_down all events ( Action_down events are not controlled by the Requestdisallowtouchevent () method Once the parent container intercepts the event, then all events cannot be passed to the child element. The internal interception method is not allowed to talk about it, so when the child element thinks that no event is needed When you call Requestdisallowintercepttouchevent (FALSE), the parent container can continue to intercept after the event of the parent container is modified as follows for fixed code

        public boolean onInterceptTouchEvent(MotionEvent ev){        int action = ev.getAction();        if(action == MotionEvetn.ACTION_DOWN){            return false;        }else{            return true;        }    }

    Reference: Android Development Art Exploration

Introduction to view Basics (II.)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.