日常开发中 , 经常会遇到顶部布局非常的长 , 以及末尾会加一个ViewPager的布局,而此时如果不加入ScrollView的话 , 那么ViewPager的可显示内容将会变得非常小 , 肯定不会符合UI妹妹内心的想法 , 所以 , 一个可滑动的ViewPager是至关重要的 , 但是ViewPager里的RecycleView又会消费掉滑动事件 , 所以本文我们就来解决它.
本文适用与刷新框架包裹NestedScrollView , 并且ViewPager在视图内占据一定位置
如果你想要的效果是NestedScrollView +ViewPager+刷新框架+RecycleView
那么请移步下一篇文章 , 下一篇文章将处理Viewpager在屏幕外的视图 , 以及在Viewpager下的刷新列表解决拖动时导致NestedScrollView的拖动.
NestedScrollView+ViewPager+下拉刷新+RecycleView的冲突解决
本文所使用的下拉框架是
implementation 'com.liaoinstan.springview:library:1.5.1'
建议使用1.5.1版本 , 是个很好用的下拉刷新框架 , 1.5.1以前的版本没用禁止上拉加载的功能
布局格式
自定义一个NestedScrollView , 可以通过滑动高度的计算 , 设置NestedScrollView是否拦截滑动事件
public class JudgeNestedScrollView extends NestedScrollView {
private boolean isNeedScroll = true;
private float xDistance, yDistance, xLast, yLast;
private int scaledTouchSlop;
public JudgeNestedScrollView(Context context) {
super(context, null);
}
public JudgeNestedScrollView(Context context, AttributeSet attrs) {
super(context, attrs, 0);
}
public JudgeNestedScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// scaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
xDistance = yDistance = 0f;
xLast = ev.getX();
yLast = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
final float curX = ev.getX();
final float curY = ev.getY();
xDistance += Math.abs(curX - xLast);
yDistance += Math.abs(curY - yLast);
xLast = curX;
yLast = curY;
return !(xDistance >= yDistance || yDistance < scaledTouchSlop) && isNeedScroll;
}
return super.onInterceptTouchEvent(ev);
}
/*
该方法用来处理NestedScrollView是否拦截滑动事件
*/
public void setNeedScroll(boolean isNeedScroll) {
this.isNeedScroll = isNeedScroll;
}
}
new Handler().postDelayed(() -> {
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) mViewPager.getLayoutParams();
layoutParams.height = (int) (ll_bootom1.getY() - (ll_title.getY() + ll_title.getHeight()) + 1);
mViewPager.setLayoutParams(layoutParams);
}, 100);
nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
int lastScrollY = 0;
@Override
public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
int[] location = new int[2];
mViewPager.getLocationOnScreen(location);
int[] location1 = new int[2];
ll_title.getLocationInWindow(location1);
int yPosition = location[1];
if (yPosition - (location1[1] + ll_title.getHeight()) < 10) {
nestedScrollView.setNeedScroll(false);
} else {
nestedScrollView.setNeedScroll(true);
}
lastScrollY = scrollY;
}
});
在onCreate下动态设置ViewPager的高度 , 注意 , ViewPager的高度的计算方法应该是屏幕的真实高度减去应用本身的标题栏高度 , 和电池栏高度 , 这样 , 在ViewPager滑动的时候 , ViewPager不会超出屏幕
即 layoutParams.height = (int) (屏幕高度- (标题栏的Y坐标 + 标题栏的高度));
具体情况根据需求判断 , 有时候Viewpager上方还会有一个 SlidingTabLayout即选项卡 , 要做到选项卡卡在屏幕上 , 以及标题栏下 , 那么Viewpager的高度应该再减去SlidingTabLayout的高度.
nestedScrollView.setNeedScroll(false);设置是否允许NestedScrollView滑动