上面是三个viewPager相互嵌套,这么就需要对滑动事件进行处理
/** * 重写onTouchEvent事件,什么都不用做,不能滑动 */ @Override public boolean onTouchEvent(MotionEvent arg0) { return false; }
// 表示事件是否拦截, 返回false表示不拦截, 可以让嵌套在内部的viewpager相应左右划的事件 @Override public boolean onInterceptTouchEvent(MotionEvent arg0) { return false; }
接下来2使用自定义viewpager,在第一个页面的时候让父控件拦截,即显示出侧边栏,但是3的话是不拦截,让侧边栏不显示出来,这样的话就相互矛盾了,到底是拦截还是不拦截了?
/** * 11个子页签水平滑动的Viewpager, 暂时不用 * * @author Kevin * */public class HorizontalViewPager extends ViewPager { public HorizontalViewPager(Context context, AttributeSet attrs) { super(context, attrs); } public HorizontalViewPager(Context context) { super(context); } /** * 事件分发, 请求父控件及祖宗控件是否拦截事件 */ @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (getCurrentItem() != 0) { getParent().requestDisallowInterceptTouchEvent(true);// 用getParent去请求, // 不拦截 } else {// 如果是第一个页面,需要显示侧边栏, 请求父控件拦截 getParent().requestDisallowInterceptTouchEvent(false);// 拦截 } return super.dispatchTouchEvent(ev); }}
所以不能按上面的第二步这样写,我们既想北京出来,又不想让北京出来
修改:菜单详情页-新闻(viewpager1),以前是通过HorizontalViewPager 来控制,而上面图片的那个类也不能那样写了,看最后一个
// mViewPager.setOnPageChangeListener(this);//注意:当viewpager和Indicator绑定时, // 滑动监听需要设置给Indicator而不是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) {//只有在第一个页面(北京), 侧边栏才允许出来 slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN); } else { slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_NONE); } }
/** * 事件分发, 请求父控件及祖宗控件不要拦截事件 */ @Override public boolean dispatchTouchEvent(MotionEvent ev) { getParent().requestDisallowInterceptTouchEvent(true);// 用getParent去请求 return super.dispatchTouchEvent(ev); }
/** * 头条新闻的Viewpager */public class TopNewsViewPager extends ViewPager { int startX; int startY; public TopNewsViewPager(Context context, AttributeSet attrs) { super(context, attrs); } public TopNewsViewPager(Context context) { super(context); } /** * 事件分发, 请求父控件及祖宗控件是否拦截事件 1. 右划, 而且是第一个页面, 需要父控件(mainactivity)拦截,菜单就出来了 2. 左划, 而且是最后一个页面, 需要父控件(viewpager2)拦截,会滑动2的下一个页面 * 3. 上下滑动, 需要父控件拦截 */ @Override public boolean dispatchTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN:(滑动停止的时候) getParent().requestDisallowInterceptTouchEvent(true);// 不要拦截, // 这样是为了保证ACTION_MOVE调用 startX = (int) ev.getRawX(); startY = (int) ev.getRawY(); break; case MotionEvent.ACTION_MOVE:(滑动的时候) int endX = (int) ev.getRawX(); int endY = (int) ev.getRawY(); if (Math.abs(endX - startX) > Math.abs(endY - startY)) {// 左右滑动 if (endX > startX) {// 右划 if (getCurrentItem() == 0) {// 第一个页面, 需要父控件拦截 getParent().requestDisallowInterceptTouchEvent(false); } } else {// 左划 if (getCurrentItem() == getAdapter().getCount() - 1) {// 最后一个页面, // 需要拦截 getParent().requestDisallowInterceptTouchEvent(false); } } } else {// 上下滑动 getParent().requestDisallowInterceptTouchEvent(false); } break; default: break; } return super.dispatchTouchEvent(ev); }}
MotionEvent中getX()和getRawX()的区别
getX是获取以widget左上角为坐标原点计算的X轴坐标直. getRawX 获取的是以屏幕左上角为坐标原点计算的X轴坐标直.
当你触到按钮时,x,y是相对于该按钮左上点的相对位置。而rawx,rawy始终是相对于屏幕的位置。