Before reading this article, it is recommended to read it first Android event distribution mechanism (1) - source code analysis_ z936689039 blog - CSDN blog
1. Case 1
We have to use the ps summary found in ViewGroup:
1. When ACTION_MOVE and action_ When the up event arrives, if no child element handles the event (mFirstTouchTarget==null), the onInterceptTouchEvent of the ViewGroup will not be called again, and other events in the same sequence will be handled by it by default (intercepted=true), which will be handled by the ViewGroup itself.
2. Once the child element calls the requestDisallowInterceptTouchEvent(true) method, the ViewGroup will not be able to intercept other events except DOWN.
1.1. External interception method:
As the name suggests, it directly intercepts the external ViewGroup. In this processing, the method of 1 is adopted, that is, the onInterceptTouchEvent is directly rewritten, and then the sub View processes the remaining events. The main points are as follows:
1. The parent class cannot intercept ACTION_DOWN, that is, action_ false must be returned when down, that is, it is not intercepted
2. The parent class is in action_ When moving, judge whether to intercept according to the demand.
3.ACTION_ The up event is recommended to return false or super.onInterceptTouchEvent, because if it has been intercepted, the onInterceptTouchEvent method will not be called to ask again. If it is not intercepted and returns true, the child View may not be able to trigger onClick and other related events.
realization:
private boolean isIntercept; private boolean isSolve;//Whether the interception judgment is completed. If it is decided to intercept, the same series of events cannot be set not to intercept @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mPointGapF.x = ev.getX(); mPointGapF.y = ev.getY(); return false;//When down, after intercepting, you can only handle it yourself case MotionEvent.ACTION_MOVE: if (!isSolve) {//Have you decided to intercept / not intercept? isIntercept = (Math.abs(ev.getX() - mPointGapF.x) > Math.abs(ev.getY() - mPointGapF.y)*2);//If it slides left and right and the horizontal angle is less than 30 °, it will be intercepted isSolve = true; } return isIntercept;//If it slides left and right, intercept it } return super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_MOVE: scrollBy((int) (mPointGapF.x - ev.getX()), 0); mPointGapF.x = ev.getX(); mPointGapF.y = ev.getY(); break; } return super.onTouchEvent(ev); }
Subview: it has nothing to do with subviews. It only needs to handle its own mobile operations.
public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mPointGapF.x = ev.getX(); mPointGapF.y = ev.getY(); break; case MotionEvent.ACTION_MOVE: scrollBy(0, (int) (mPointGapF.y - ev.getY())); mPointGapF.x = ev.getX(); mPointGapF.y = ev.getY(); break; } return true; }
1.2. Internal interception
Using the knowledge of 2,
ViewGroup: just click onintercepttucheventmotionevent.action_ It is not intercepted when down, and it needs to be intercepted at other times, otherwise the onTouchEvent of the parent class cannot handle any events.
public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: return false;//When down, after intercepting, you can only handle it yourself } return true;//If not intercepted, the onTouchEvent method of the parent class has no events to handle. } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_MOVE: scrollBy((int) (mPointGapF.x - ev.getX()), 0); mPointGapF.x = ev.getX(); mPointGapF.y = ev.getY(); break; } return super.onTouchEvent(ev); }
Subview: need to be in action_ The down event is set to getParent().requestDisallowInterceptTouchEvent(true), and is set in action_ When moving, judge whether to prohibit the interception of the parent class.
private boolean isSolve; private boolean isIntercept; @Override public boolean dispatchTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: isIntercept = false; isSolve = false; mPointGapF.x = ev.getX(); mPointGapF.y = ev.getY(); getParent().requestDisallowInterceptTouchEvent(true); break; case MotionEvent.ACTION_MOVE: if (!isSolve) { isSolve = true; isIntercept = (Math.abs(ev.getX() - mPointGapF.x) < Math.abs(ev.getY() - mPointGapF.y) * 2); getParent().requestDisallowInterceptTouchEvent(isIntercept); } break; } return super.dispatchTouchEvent(ev); }
2. Case 2
For the two sliding conflicts with the same sliding direction, the processing method is the same as the external interception method in case 1, which is also solved by using the knowledge points in summary 2: for example Sliding conflict between ScrollView and EditText_ z936689039 blog - CSDN blog
Reference article: