当前位置:网站首页>Analyze Android event distribution mechanism according to popular interview questions (II) -- event conflict analysis and handling

Analyze Android event distribution mechanism according to popular interview questions (II) -- event conflict analysis and handling

2022-07-07 09:52:00 Time swordsman

( One ) Overview of incident conflict

Event conflicts usually occur in the parent view Hezi view Combination of , for instance viewpager and listview Combination of . The cause of the event conflict is an event (down,up,move) When we arrive , Sometimes we want to be A view Handle , But it was B view Handle . This leads to what we want to deal with view No events , Don't want to deal with events view Received the incident . And to solve the conflict is to pass viewGroup Of onInterceptTouchEvent() Methods to distribute events reasonably , Let those who want to deal with the event view Received the incident , Don't want to deal with it view Lie flat and do nothing .

( Two ) There is no effect display of event conflict

 Insert picture description here ( Look at the beauty , Write code again ~~)
Get down to business , As shown in the figure above ,demo Is written by a viewpager+listView The combination of , We found that in the case of no event conflict , It should be able to slide left and right , It can also slide up and down . To demonstrate , We inherit from viewpager and Listview,viewPager As a father view, Rewrite its onInterceptTouchEvent Method ,listview As a child view, rewrite dispatchTouchevent.( When needed ),demo The source code of is very simple , I'll give it at the end of the article .
( explain : If you do not override onInterceptTouchEvent and listview Of dispatchTouchevent Method , We use it directly viewpager+listview The combination will find that there will be no event conflict , That's because sdk The conflict has been resolved , You can see viewpager Source code )

Simulate the generation of conflict
scene 1: When we are in the father view, That is to say viewPager Of onInterceptTouchEvent Method to return true, Intercept the incident , At this time, we will find that we can only respond view pager Slide left and right , And cannot respond listview Slide up and down , The reason is that we are in the father view Directly intercepted the event , Lead to view listview No events , Unable to respond to events .
scene 2: When we are in the father view, That is to say viewPager Of onInterceptTouchEvent Method to return false, Don't intercept events , At this time, we will find ,viewpager Do not slide left or right , It can only slide up and down listview, This is because viewpager Don't intercept events , Distributed the event to the child view Handle , So he can't respond to his left-right sliding event .

( 3、 ... and ) Interview questions : Have you ever encountered sliding conflict ? How did you handle it ?

analysis : At this time, if you have met , Just answer the situation caused by the conflict you encounter , Then say your solution , If you haven't met , Just answer what we mentioned in this article viewpager+listview Scene . Summarize according to the above content , Then there is the answer of how to solve the conflict , At this time, you can answer that there are two ways to solve the conflict :
Method 1 : In the father view Of onInterceptTouchEvent Conflict resolution in , The code is as follows :

   @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
    
        // In the father view Conflict handling in , There is no need for children view Realization dispatchTouchEvent Method 
        float x = ev.getX();// Record x,y The initial value of the 
        float y = ev.getY();
        switch (ev.getAction()){
    
            case MotionEvent.ACTION_DOWN:      
                super.onInterceptTouchEvent(ev);
                // You need to call sdk Medium viewpager Medium 
                //onInterceptTouchEvent Methods to deal with some special problems 
                // If we don't call, we can't respond to sliding even if we intercept the event 
                return false;// Can't intercept down event , Intercepted down
                // event , You can't receive the following move, and up The incident is over 
            case MotionEvent.ACTION_MOVE:
                float xDiff = Math.abs(x-mLastX);
                // When move When the event comes, we will calculate this x Value and last 
                //x value , You get a difference 
                float yDiff = Math.abs(y-mLastY);
                //y The calculation of the value and x equally 

                if(xDiff > yDiff){
    //x The difference is greater than y The difference between the , Indicates that the current is sliding left and right . At this time, the event should be handed over to viewpager Handle , Intercept the incident 
                    isIntercept = true;
                    break;
                }

                if(yDiff > xDiff){
    //y Greater than x value , Indicates that it is currently sliding up and down , At this time, the event should be handed over to listview Handle , Don't intercept events 
                    isIntercept = false;
                    break;
                }
              // break;

        }
      
        mLastX = x;// Update the last x Values and y value 
        mLastY = y;

        return isIntercept;
    }

Method 2: In the child view Do sliding conflict processing in ,listview The code in is as follows :

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
    
        float x = ev.getX();
        float y = ev.getY();
        switch (ev.getAction()){
    
            case MotionEvent.ACTION_DOWN:
                getParent().requestDisallowInterceptTouchEvent(true);
                // Ask the father view Don't intercept events 
                break;
            case MotionEvent.ACTION_MOVE:
                float xDiff = Math.abs(x-mLastX);
                float yDiff = Math.abs(y-mLastY);

                if(xDiff > yDiff){
    
                // Currently, it slides left and right , You don't need to deal with events , Ask the father view Intercept the incident .
                    getParent().requestDisallowInterceptTouchEvent(false);
                }

                break;
            default:break;

        }

        mLastX = x;
        mLastY = y;
        // Calling the dispatchTouchEvent Handling events 
        return super.dispatchTouchEvent(ev);
    }

viewPager The code in is as follows :

 @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
    
        // In the child view Conflict handling in .
        if(ev.getAction() == MotionEvent.ACTION_DOWN){
    
            super.onInterceptTouchEvent(ev);
            // Must return false, Otherwise the child view Unable to receive event , There will be an interview question here 
            return false;
        }
        // return true, To be a son view Ask the father view When intercepting events , Good interception 
        return true;
 }

In the child view Handle conflicts in and in the parent view The principle of dealing with conflicts is similar , Events are distributed to those who need them through interception and non interception view. When answering, roughly describe the two methods .
And then , The interviewer may ask you : Why not intercept down event , Intercepted down event , hinder move,up Can the event still be received ?
These two problems are actually mutually causal , That is to intercept down event , hinder move,up Events cannot be received . At this time, you can start to put out the source code of the event distribution mechanism you see :

... Some code is omitted 
// Check for interception.
            final boolean intercepted;
            if (actionMasked == MotionEvent.ACTION_DOWN
                    || mFirstTouchTarget != null) {
    
                final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
                // If son view There is no call requestDisallowInterceptTouchEvent Method to set the flag , This place will be false, Because in the front down The flag will be reset when the event comes 
                if (!disallowIntercept) {
    
                    intercepted = onInterceptTouchEvent(ev);// If intercepted down event , This place will return true; Unable to enter the next event distribution logic , then mFirstTouchTarget Will not be assigned , Cannot walk into the current code logic , Cause the following move and up The event will be directly intercepted 
               ============= Episode ==============
                     if (!canceled && !intercepted) {
    
                     ....
                    //  Event distribution processing logic 
                    .....
                     }
               ===========================
                    ev.setAction(action); // restore action in case it was changed
                } else {
    
                    intercepted = false;
                }
            } else {
    
                // There are no touch targets and this action is not an initial down
                // so this view group continues to intercept touches.
                // If not dealt with down At the time of the event ,move and up Events will be intercepted 
                intercepted = true;
            }
 ... Some code is omitted 

Specific event distribution process , See my last blog According to the analysis of popular interview questions Android Event distribution mechanism ( One )

( Four ) summary :

In fact, event distribution mechanism and sliding conflict are not difficult to solve as long as you understand the source code , My suggestion is to read the blog and then go to the source code by yourself , Write demo Simulate every scenario , Then you will find that these principles are all true , It can also help you get the initiative during the interview , Most of the time when we interview, we feel overwhelmed by the interviewer's momentum , In fact, it's all because we don't know much about technology . When we have a thorough understanding of Technology , When you go to the interview, you will find , The interviewer will be abused by you . That feeling is very cool

( 5、 ... and )demo Address

I put this source code in gitee Upper , You have applied for opening permission , It's still being approved , If you urgently need a partner of the source code , You can leave an email , I send it to you in private ~~~~
Event conflict demonstration demo Address

原网站

版权声明
本文为[Time swordsman]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207070702497261.html