ViewPager 嵌套滑动事件冲突问题解决方案:
1:重写 子 ViewPager onTouchEvent :
相关文章地址:
http://stackoverflow.com/questions/7098868/viewpager-inside-viewpager
1:重写 子 ViewPager onTouchEvent :
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.PointF;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
public class SubViewPager extends ViewPager {
/**
* @Description Constructor
* @param context
*/
public SubViewPager(Context context) {
super(context,null);
}
/**
* @Description Constructor
* @param context
* @param attrs
*/
public SubViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
/*PointF downPoint = new PointF();
OnSingleTouchListener onSingleTouchListener;
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent evt) {
switch (evt.getAction()) {
case MotionEvent.ACTION_DOWN:
// 记录按下时候的坐标
downPoint.x = evt.getX();
downPoint.y = evt.getY();
if (this.getChildCount() > 1) { // 有内容,多于1个时
// 通知其父控件,现在进行的是本控件的操作,不允许拦截
getParent().requestDisallowInterceptTouchEvent(true);
}
break;
case MotionEvent.ACTION_MOVE:
if (this.getChildCount() > 1) { // 有内容,多于1个时
// 通知其父控件,现在进行的是本控件的操作,不允许拦截
getParent().requestDisallowInterceptTouchEvent(true);
}
break;
case MotionEvent.ACTION_UP:
// 在up时判断是否按下和松手的坐标为一个点
if (PointF.length(evt.getX() - downPoint.x, evt.getY() - downPoint.y) < (float) 5.0) {
onSingleTouch(this);
return true;
}
break;
}
return super.onTouchEvent(evt);
}
public void onSingleTouch(View v) {
if (onSingleTouchListener != null) {
onSingleTouchListener.onSingleTouch(v);
}
}
public interface OnSingleTouchListener {
public void onSingleTouch(View v);
}
public void setOnSingleTouchListener(OnSingleTouchListener onSingleTouchListener) {
this.onSingleTouchListener = onSingleTouchListener;
}
*/
/** 触摸时按下的点 **/
PointF downP = new PointF();
/** 触摸时当前的点 **/
PointF curP = new PointF();
private boolean mIsBeingDragged=true;
OnSingleTouchListener onSingleTouchListener;
@Override
public boolean onInterceptTouchEvent(MotionEvent arg0) {
// 当拦截触摸事件到达此位置的时候,返回true,
// 说明将onTouch拦截在此控件,进而执行此控件的onTouchEvent
return true;
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent arg0) {
// 每次进行onTouch事件都记录当前的按下的坐标
curP.x = arg0.getX();
curP.y = arg0.getY();
switch (arg0.getAction()) {
case MotionEvent.ACTION_DOWN:
if(getCurrentItem()<=0 || getCurrentItem()>=getChildCount()){
mIsBeingDragged = false;
getParent().requestDisallowInterceptTouchEvent(false);
}else{
// 记录按下时候的坐标
// 切记不可用 downP = curP ,这样在改变curP的时候,downP也会改变
downP.x = arg0.getX();
downP.y = arg0.getY();
// 此句代码是为了通知他的父ViewPager现在进行的是本控件的操作,不要对我的操作进行干扰
mIsBeingDragged = true;
getParent().requestDisallowInterceptTouchEvent(true);
}
break;
case MotionEvent.ACTION_MOVE:
if(getCurrentItem()<=0 || getCurrentItem()>=getChildCount()){
mIsBeingDragged = false;
getParent().requestDisallowInterceptTouchEvent(false);
}else{
// 此句代码是为了通知他的父ViewPager现在进行的是本控件的操作,不要对我的操作进行干扰
mIsBeingDragged = true;
getParent().requestDisallowInterceptTouchEvent(true);
}
break;
case MotionEvent.ACTION_UP:
// 在up时判断是否按下和松手的坐标为一个点
// 如果是一个点,将执行点击事件,这是点击事件,而不是onclick
if (downP.x == curP.x && downP.y == curP.y) {
if (onSingleTouchListener != null) {
onSingleTouchListener.onSingleTouch(curP.x,curP.y);
}
return true;
}
break;
case MotionEvent.ACTION_CANCEL:
if(mIsBeingDragged) {
getParent().requestDisallowInterceptTouchEvent(false);
}
break;
default:
break;
}
return super.onTouchEvent(arg0);
}
/**
* 创建点击事件接口
*/
public interface OnSingleTouchListener {
public void onSingleTouch(float touchX,float touchY);
}
public void setOnSingleTouchListener(OnSingleTouchListener onSingleTouchListener) {
this.onSingleTouchListener = onSingleTouchListener;
}
}
ViewPager 中的Button事件需要根据坐标点来处理
2.重写 父 ViewPager 中的 canScroll 方法:
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.View;
public class ParentViewPager extends ViewPager {
/**
* @Description Constructor
* @param context
*/
public ParentViewPager(Context context) {
super(context);
}
/**
* @Description Constructor
* @param context
* @param attrs
*/
public ParentViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
if (v != this && v instanceof ViewPager) {
ViewPager childViewPager = (ViewPager) v;
int currentItem = childViewPager.getCurrentItem();
int countItem = childViewPager.getAdapter().getCount();
if ((currentItem == (countItem - 1) && dx < 0) || (currentItem == 0 && dx > 0)) {
return false;
}
return true;
}
return super.canScroll(v, checkV, dx, x, y);
}
}
相关文章地址:
http://stackoverflow.com/questions/7098868/viewpager-inside-viewpager
http://www.cnblogs.com/xitang/archive/2013/07/09/3179649.html