代码结构
1.最外层是一个ViewPager
2.ViewPager的每个item又是一个ExpandableListview
3.ExpandableListview的childItem是一个单行的ViewPager
问题描述
-
滑动最底层的ViewPager时,很容易引起最外层的ViewPager滑动
截图.png
解决思路
1.分析最外层ViewPager的onIntercepterTouchEvent方法的代码可以知道,在MotionEvent.ACTION_MOVE中会调用canScroll方法
if (dx != 0 && !isGutterDrag(mLastMotionX, dx)
&& canScroll(this, false, (int) dx, (int) x, (int) y)) {
// Nested view has scrollable area under this point. Let it be handled there.
mLastMotionX = x;
mLastMotionY = y;
mIsUnableToDrag = true;
return false;
}
2.查看canScroll源码
/**
* Tests scrollability within child views of v given a delta of dx.
*
* @param v View to test for horizontal scrollability
* @param checkV Whether the view v passed should itself be checked for scrollability (true),
* or just its children (false).
* @param dx Delta scrolled in pixels
* @param x X coordinate of the active touch point
* @param y Y coordinate of the active touch point
* @return true if child views of v can be scrolled by delta of dx.
*/
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
if (v instanceof ViewGroup) {
final ViewGroup group = (ViewGroup) v;
final int scrollX = v.getScrollX();
final int scrollY = v.getScrollY();
final int count = group.getChildCount();
// Count backwards - let topmost views consume scroll distance first.
for (int i = count - 1; i >= 0; i--) {
// TODO: Add versioned support here for transformed views.
// This will not work for transformed views in Honeycomb+
final View child = group.getChildAt(i);
if (x + scrollX >= child.getLeft() && x + scrollX < child.getRight()
&& y + scrollY >= child.getTop() && y + scrollY < child.getBottom()
&& canScroll(child, true, dx, x + scrollX - child.getLeft(),
y + scrollY - child.getTop())) {
return true;
}
}
}
return checkV && v.canScrollHorizontally(-dx);
}
从参数说明中就很容易知道,如果子view可以滑动,返回为true
3.在自定义的最外层ViewPager中重写canScroll()方法
public class HomeViewPager extends ViewPager {
public HomeViewPager(Context context) {
this(context, null);
}
public HomeViewPager(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
|| v instanceof CartoonRecycleView
|| v instanceof SingleLineZoomScrollView)) {
return true;
} else if (v != this && v instanceof GridView) {
return false;
}
return super.canScroll(v, checkV, dx, x, y);
}
}
最底层的ViewPager我是放在SingleLineZommScrollView当中的,故当手指滑动在此控件范围中canScroll返回true,问题完美解决。
网友评论