上下滚动控件嵌套左右滚动控件的时候(如listview,RecyclerView,ScrollView嵌套viewpager,HorizontalScrollView等)
此知识点和ontouch分发操作有关,如果不懂的最好先补脑ontouch分发
简单明了,直接说解决办法方法一:继承最外层原控件,并在此继承控件上,判断手势触摸的移动方向,如果上下滑动大于左右滑动的临界值。则此控件拦截并交给自己继承的控件处理,如果左右滑动大于上下滑动的临界值,则不交给自己处理
private float mDownX; private float mDownY;
/*public PtrClassicDefaultHeader getHeader() { return mPtrClassicHeader; }*/
private float mDownX; private float mDownY; public PtrClassicDefaultHeader getHeader() { return mPtrClassicHeader; } @Override public boolean dispatchTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mDownX = ev.getX(); mDownY = ev.getRawY(); break; case MotionEvent.ACTION_MOVE: float moveX = ev.getX(); float moveY = ev.getRawY(); float diffX = Math.abs(moveX - mDownX); float diffY = Math.abs(moveY - mDownY); boolean isHorizon = diffY / diffX < Math.tan(Math.toRadians(45.0)); if (isHorizon) { return dispatchTouchEventSupper(ev); } break; } return super.dispatchTouchEvent(ev); }
//看一眼原父布局的方法是这样写的
public boolean dispatchTouchEventSupper(MotionEvent e) { return super.dispatchTouchEvent(e); }
方法二:监听内部嵌套布局的滑动,如果没有监听到抬起操作,则屏蔽父布局,否则屏蔽此布局(原生控件直接用,自定义控件往下看)
((FindFragment.HeaderViewHolder) holder).recycleView_item.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { //触摸返回值 // int action = motionEvent.getAction(); if (motionEvent.getAction() == MotionEvent.ACTION_UP) { ptrFrame.requestDisallowInterceptTouchEvent(false); } else { ptrFrame.requestDisallowInterceptTouchEvent(true); } return false; } });
如果父布局是自定义控件,那么在这个父布局重写控件的类中加入如下方法
private boolean disallowInterceptTouchEvent = false; @Override public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { disallowInterceptTouchEvent = disallowIntercept; super.requestDisallowInterceptTouchEvent(disallowIntercept); } @Override public boolean dispatchTouchEvent(MotionEvent e) { if (disallowInterceptTouchEvent) { return dispatchTouchEventSupper(e); } return super.dispatchTouchEvent(e); }