Sliding event handling

Posted by mk_silence on Wed, 12 Jan 2022 06:44:53 +0100

The above three viewpagers are nested with each other, so the sliding event needs to be handled

  • First of all, we don't need viewpager1 to slide, because its parent control intercepts its events every time it slides, and the sidebar runs out every time it slides, so here's how to handle it: use a custom viewpager and override its method
   /**	 * Rewrite the onTouchEvent event. You don't have to do anything. You can't slide	 */	@Override	public boolean onTouchEvent(MotionEvent arg0) {		return false;	}
  • viewpager2 is in 1. 2 wants to slide, but 1 can't slide. It intercepts the sliding event of 2, so 2 can't slide. Here, rewrite the custom viewpager of 1
	// Indicates whether the event is intercepted. If false is returned, it indicates that it is not intercepted. You can make the nested viewpager delimit the events to the left and right accordingly 	@ Override 	 public boolean onInterceptTouchEvent(MotionEvent arg0) { 		 return false; 	}

Next, 2 use the custom viewpager to let the parent control intercept on the first page, that is, the sidebar is displayed. However, 3 does not intercept and the sidebar is not displayed. In this way, it is contradictory. Is it intercepted or not?

/** * 11 The child tab is a horizontal sliding Viewpager, and * * @ author Kevin is not used for the time being*  */public class HorizontalViewPager extends ViewPager {	public HorizontalViewPager(Context context, AttributeSet attrs) {		super(context, attrs);	}	public HorizontalViewPager(Context context) {		super(context);	}	/**	 * Event distribution, request whether the parent control and ancestor control intercept events	 */	@Override	public boolean dispatchTouchEvent(MotionEvent ev) {		if (getCurrentItem() != 0) {			getParent().requestDisallowInterceptTouchEvent(true);// Request with GetParent, 																	//  No interception 		}  else {/ / if it is the first page, you need to display the sidebar and request the parent control to intercept it 			 getParent().requestDisallowInterceptTouchEvent(false);//  intercept 		}		 return super.dispatchTouchEvent(ev); 	}}

Therefore, we can't follow the second step above. We both want Beijing to come out and don't want Beijing to come out

Modification: the menu details page - News (viewpager1) was previously controlled by the HorizontalViewPager, and the type of picture above can't be written like that. See the last one

	// mViewPager.setOnPageChangeListener(this);// Note: when viewpager and Indicator are bound, 		//  Sliding monitoring needs to be set to Indicator instead of viewpager 		 mIndicator.setOnPageChangeListener(this);
@Override	public void onPageSelected(int arg0) {		System.out.println("onPageSelected:" + arg0);		MainActivity mainUi = (MainActivity) mActivity;		SlidingMenu slidingMenu = mainUi.getSlidingMenu();		if (arg0 == 0) {//The sidebar is only allowed on the first page (Beijing) 			 slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN); 		}  else { 			 slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_NONE); 		}	}
  • Next, I wrote indicator, but when I found that indicator was sliding, I would pull out the sidebar, because the sidebar intercepted its sliding events. Modify the source code of indicator tabpageindicator java
	/**	 * For event distribution, request the parent control and ancestor control not to intercept events	 */	@Override	public boolean dispatchTouchEvent(MotionEvent ev) {		getParent().requestDisallowInterceptTouchEvent(true);// Request with getParent 		 return super.dispatchTouchEvent(ev); 	}
  • viewpager3 will slide to the head or tail and can't be scratched, but we don't want this effect. Customize viewpager
/** * Viewpager for headlines */public class TopNewsViewPager extends ViewPager {	int startX;	int startY;	public TopNewsViewPager(Context context, AttributeSet attrs) {		super(context, attrs);	}	public TopNewsViewPager(Context context) {		super(context);	}	/**	 * Event distribution, request whether the parent control and ancestor control intercept event 1 Right click, and it is the first page. It needs to be intercepted by the parent activity, and the menu will come out. 2 Left stroke, and it is the last page. It needs to be intercepted by the parent control (viewpager2), which will slide the next page of viewpager2 	 *  3. Sliding up and down requires the parent control to intercept	 */	@Override	public boolean dispatchTouchEvent(MotionEvent ev) {		switch (ev.getAction()) {		case MotionEvent.ACTION_DOWN:((when sliding stops)			getParent().requestDisallowInterceptTouchEvent(true);// Don't intercept, 																	//  This is to ensure ACTION_MOVE call 			 startX = (int) ev.getRawX(); 			 startY = (int) ev.getRawY(); 			 break; 		 case MotionEvent.ACTION_MOVE: (when sliding) 			 int endX = (int) ev.getRawX(); 			 int endY = (int) ev.getRawY(); 			 if (Math.abs(endX - startX) > Math. ABS (Endy - starty)) {/ / slide left and right 				 If (endx > startx) {/ / right stroke 					 if (getCurrentItem() == 0) {/ / the first page needs to be intercepted by the parent control 						 getParent().requestDisallowInterceptTouchEvent(false); 					}				}  else {/ / left stroke 					 if (getCurrentItem() == getAdapter().getCount() - 1) {/ / last page, 																			//  Need to intercept 						 getParent().requestDisallowInterceptTouchEvent(false); 					}				}			}  else {/ / slide up and down 				 getParent().requestDisallowInterceptTouchEvent(false); 			}			 break; 		 default: 			 break; 		}		 return super.dispatchTouchEvent(ev); 	}}

The difference between getX() and getRawX() in MotionEvent

getX is to obtain the X axis coordinates calculated with the upper left corner of the widget as the coordinate origin getRawX obtains the x-axis coordinates calculated with the upper left corner of the screen as the coordinate origin

When you touch a button, x and y are the relative positions relative to the upper left point of the button. Rawx and rawy are always relative to the screen.

From Weizhi notes (Wiz)