The solution to the sliding conflict problem caused by Viewpager in Android app _android

Source: Internet
Author: User
Tags abs

Narrative
sliding conflict can be said to be common in the daily development of a class of problems, but also a problem of a more annoying, especially in the use of Third-party frameworks, two of the original perfect control, together, suddenly found the whole world is not good.

About sliding conflicts
Sliding Conflict Classification:
Sliding conflicts, in general, are two categories.

1. Sliding conflict in the same direction
such as ScrollView nesting listview, or scrollview nesting themselves

2. Sliding conflict in different directions
such as ScrollView nesting viewpager, or viewpager nesting scrollview, this situation is very typical. Now most of the application outermost is the viewpager+fragment of the bottom of the switch (such as micro-letter) structure, this time, it is easy to slip conflict. But Viewpager inside whether is nested ListView or ScrollView, sliding conflict is not, after all, is the official thing, may have taken into account these, so relatively perfect.

The complicated sliding conflict is basically the result of the combination of these two conflicts.

The idea of sliding conflict resolution
sliding conflict, in its essence, two different directions (or the same direction) of the view, one of which is dominant, always grab to deal with the external sliding behavior, which leads to a very awkward user experience, obviously just sideways sliding a bit, The vertical list takes action in the vertical direction. So, this dominant view, each time involuntarily intercepted this sliding action, therefore, to solve the sliding conflict, is to clearly tell the dominant view, when you should intercept, when you should not intercept, should be the next layer of view to deal with this sliding action.

This does not understand the classmate, you can go to understand the Android touch event distribution mechanism, which is the core knowledge to resolve the sliding conflict.

The second kind of sliding conflict, the solution is relatively simple. Here is a combination of examples to say.

Here, let's talk about the background. Before doing a drop-down refresh, pull load more always use the Pulltorefreshview this control, because it is very convenient, do not import the three-party project. In its interior can be placed Listview,gridview and ScrollView, very convenient, use it is a proven. But until one day, as a result of the project needs, at the top of the ListView add a wheel map control Bannerview. The results show that the carousel is sliding, and the vertical drop-refresh component is flushed.
As mentioned before, the key to solving sliding conflicts is to explicitly tell the view that received the touch, whether or not to intercept the event.

Workaround:
Solution 1, consider from an external interception mechanism
here, the equivalent is Pulltorefreshview nested viewpager, then each priority received touch event is necessarily pulltorefreshview. So it's clear, look at the code:

In the Pulltorefreshview:

 @Override Public
  Boolean onintercepttouchevent (Motionevent e) {
    int y = (int) e.getrawy ();
    int x = (int) e.getrawx ();
    Boolean resume = false;
    Switch (e.getaction ()) {case
      Motionevent.action_down:
        //When a Down event occurs, the record y coordinate
        mlastmotiony = y;
        Mlastmotionx = x;
        Resume = false;
        break;
      Case Motionevent.action_move:
        //deltay > 0 is down motion,< 0 is up motion
        int deltay = y-mlastmotiony;
        int deleax = X-mlastmotionx;

        if (Math.Abs (DELEAX) > Math.Abs (DeltaY)) {
          resume = false;
        } else {
        //is currently in slide
          if ( Isrefreshviewscroll (DeltaY)) {
            resume = true;
          }
        }
        break;
      Case MOTIONEVENT.ACTION_UP: Case
      motionevent.action_cancel: Break
        ;
    }
    return resume;
  }

The most critical code here is this line.

if (Math.Abs (DELEAX) > Math.Abs (DeltaY)) {
          resume = false;
        }

When the transverse sliding distance is greater than the longitudinal, there is no need to intercept this sliding event. In fact, it is that simple, but only if you have a clear understanding of the Android touch event delivery mechanism, the sequence and meaning of each method.

Solution 2, from the content of reverse thinking analysis
Sometimes, we do not want to modify the introduced Third-party controls, or to say that they cannot be modified. You have to consider the reverse of the view from the current one in the touch delivery event. First of all, from the Android view of the touch event delivery mechanism, we know that touch events, first of all, must be intercepted by the outermost view, if you can not change the outermost view, then is not the case? In fact, Android is so big on the system must take into account this problem, good nonsense do not say, first look at the code

  Private Bannerview Carouselview;

  Private context Mcontext;

  Private Pulltorefreshview Refreshview; ... refreshview.setontouchlistener (new View.ontouchlistener () {@Override public boolean Ontouch View
        V, motionevent event) {carouselview.getparent (). Requestdisallowintercepttouchevent (false);
      return false;

    }
    }); Carouselview.setontouchlistener (New View.ontouchlistener () {@Override public boolean ontouch (View V, Motionev
        Ent event) {carouselview.getparent (). Requestdisallowintercepttouchevent (True);
        int x = (int) event.getrawx ();

        int y = (int) Event.getrawy ();
            Switch (event.getaction ()) {Case MotionEvent.ACTION_DOWN:lastX = x;
            Lasty = y;
          Break
            Case MotionEvent.ACTION_MOVE:int DeltaY = y-lasty;
            int deltax = X-LASTX; if (Math.Abs (DeltaX) < Math.Abs (DeltaY)) {CarouselvieW.getparent (). Requestdisallowintercepttouchevent (false);
            else {carouselview.getparent (). Requestdisallowintercepttouchevent (True);
        } Default:break;
      return false;

 }
    });

Tell me about this method.

public abstract void Requestdisallowintercepttouchevent (Boolean disallowintercept)

Child view this method can be called if you do not want its parent view to intercept the touch event. When disallowintercept this argument is true, the parent view will not intercept.
Okay, here we are. Here the interception is straightforward and clear, and in the Carouselview Ontouch method, the parent view is set to not intercept the event, and then at motion_move time, Depending on the distance of the slide, the decision is whether the parent view has the right to intercept the touch event (i.e. sliding behavior).

Viewpager No sliding
or we simply ban the slide:

public class Customviewpager extends Viewpager {
 
  private Boolean ispagingenabled = true;
 
  Public Customviewpager {
    super (context);
  }
 
  Public Customviewpager (context, AttributeSet attrs) {
    Super (context, attrs);
  }
 
  @Override Public
  Boolean ontouchevent (Motionevent event) {return
    this.ispagingenabled && Super.ontouchevent (event);
  }
 
  @Override Public
  Boolean onintercepttouchevent (Motionevent event) {return
    this.ispagingenabled && Super.onintercepttouchevent (event);
  }
 
  public void setpagingenabled (Boolean b) {
    this.ispagingenabled = b;
  }}

Related Article

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.