New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
解决android-Ultra-Pull-To-Refresh下拉刷新组件中嵌套ViewPager的一个bug #133
Comments
我试了下,按照你的博客来,还是没能解决问题。ViewPager可正常滑动,但是此时下拉刷新却很容易出不来。 |
|
试了下,没什么效果,可能是因为我用的是第三方的banner,不是原生ViewPager的缘故。 |
将 public boolean dispatchTouchEvent(MotionEvent e) {
} move事件中的 if (mDisableWhenHorizontalMove && !mPreventForHorizontal && (Math.abs(offsetX) > mPagingTouchSlop && Math.abs(offsetX) > Math.abs(offsetY))) {
if (mPtrIndicator.isInStartPosition()) {
mPreventForHorizontal = true;
}
}
if (mPreventForHorizontal) {
return dispatchTouchEventSupper(e);
} 修改为: if (mDisableWhenHorizontalMove && (Math.abs(offsetX) > mPagingTouchSlop && Math.abs(offsetX) > Math.abs(offsetY * mPtrIndicator.getResistance()))) {
return dispatchTouchEventSupper(e);
} 然后将
感谢 @liaohuqiu 提供这么伟大的库,我从中学到了很多。 |
@Aspsine 你好,你的这种改法也是解决不了问题啊,我用的是GridView里面有Item是横向RecyclerView,还有轮播图ViewPager,都有点问题,横向滑动时,都会往下一点移动,导致不能横向 |
@ixiaoluo |
@Aspsine 请问你更新在哪里。 |
@mmchong3173 |
@Aspsine 我看到了,那意味着我只能下载源码修改后再依赖到项目里面咯?我现在是这么使用的compile 'in.srain.cube:ultra-ptr:1.0.11' |
@mmchong3173 |
@Aspsine 你好,我试了你的方案,发现viewpager在move的过程中只要稍稍有垂直方向的移动便会回到原来的位置,实际效果就是很难翻页。我的xml布局是直接在PtrFrameLayout里面嵌套一个v4包的Viewpager,而且我也把此方案放到了该项目的demo中,效果也是一样的,不知道是不是我使用的方式不对,望能指出,谢谢。 |
@ixiaoluo 看了一下描述的问题 , 昨天我也碰见场景跟你类似的问题 ,倒是解决了 , 我先说下我的场景 , 整个APP 最外层用viewpager做的各种子页面 , 每一个子页面头部是一个广告栏(viewpager实现的轮播banner)和listview 或者是gridView,ps:我的是gridview , 为了解决banner和gridview一起滚动 , 我将banner 做成了gridview 的header , 发现 banner的横向滚动不起作用 , 起初怀疑是最外层的viewpager拿走了banner里面viewpager的事件 , 就将外层viewpager 当作参数传递进来 , 在dispatchTouchEvent的时候调用外层viewpager.requestDisallowInterceptTouchEvent(true),也不起作用 , 然后我开始 怀疑是PtrFrameLayout拿走了事件 ,但是看了看PtrFrameLayout的事件分发的代码 , 如果设置了disableWhenHorizontalMove(true),PtrFrameLayout不会去终止横向的事件的 , 那么最后只剩下最后一个父控件阻止了事件,就是gridview了 , 然后我尝试在dispatchTouchEvent 禁用gridview的事件 , 结果还真好了 。 至于原因看gridview 对事件的处理 , gridview的父类AbsListView.onInterceptTouchEvent 有好几处reture true 终止事件的地方 ,并且没有判断横向移动 。 所以可以尝试我的方法 。 如果在问题再联系。 |
在以上代码中,作者的 |
发现只要PtrFrameLayout的里面的content不处在屏幕的最顶部,viewpager的滑动就没有问题。 |
有正解吗 |
PtrFrameLayout里面包ScrollView, 然后ScrollView里面又嵌套ViewPager, 现在还存在这个问题, 不知道有解决办法了每 |
@Aspsine 大神,我按照你给的方案修改了,但是效果还是不理想,我viewpager里面的一个页面有轮播图。轮播图是在listview的顶部,滑动轮播图还是会触发下拉刷新的效果 |
我找到了一个解决这个问题的好方法,代码如下:
我使用这段代码,效果挺好的。只要是滑动 我测试了这个项目和官方的下拉刷新控件,都能完美解决问题。我相信这段代码同样适用于你们的问题。 |
@18671183990 这样向左侧滑、向右侧滑、下拉,还是体验不好吧?
为了拿到准确的rect,需要ViewPage放在ViewGroup Layout中,activity_view_pager.xml。
|
目前我通过修改
其中第三种滑动没有问题,没有冲突,主要就是第一种和第二种。需要修改的代码仅仅一行: if (mDisableWhenHorizontalMove && !mPreventForHorizontal && (Math.abs(offsetX) > mPagingTouchSlop && Math.abs(offsetX) > Math.abs(offsetY))) {
if (mPtrIndicator.isInStartPosition()) {
mPreventForHorizontal = true;
}
} 把上述代码的 if (mDisableWhenHorizontalMove && !mPreventForHorizontal && Math.abs(offsetX) > Math.abs(offsetY)) {
if (mPtrIndicator.isInStartPosition()) {
mPreventForHorizontal = true;
}
} 原因是,我们既然要禁用横向滑动的拦截,那么判断操作为横向并且要禁用横向拦截时给 |
我的情况是ListView的Header中有一个ViewPager,有冲突,试了上面的一些方法都不太理想,后来给ViewPager添加了touch监听,在down的时候设置mPtrFrame.setEnabled(false),然后move时判断 |
@captain-miao 是的,虽然比改之前好多了,但体验确实有问题,多谢大神提醒. |
不知道在listview中有一个heard是横向的recycleview怎么解决呢。最外层是ptrframeayout |
@q232916067 你看下我在上面的一条回复,按照我那样重写之后,调用 |
@yanzhenjie,按照你的方案修改,OK了,感谢你的方案! |
@yanzhenjie 你好,我参考你的代码,去掉了Math.abs(offsetX) > mPagingTouchSlop,但是横向滑动还是很不灵敏。我是在recyclerView 嵌套了 ViewPager。 |
@LuoboDcom 按照我那样重写之后,调用PtrFrameLayout.disableWhenHorizontalMove(true)应该就好了。这样会禁用左右滑动的,所以应该没有问题,重写了之后要用新的代码的类喔,不要忘记要在禁用左右滑动的地方调用PtrFrameLayout.disableWhenHorizontalMove(true)。 |
@yanzhenjie 谢谢,按照你的方法,可以了。就是下拉刷新时,可以看到recyclerView被下拉了,但是header没出来,所以,感觉下拉的灵敏度变低了 |
能不能把改的放到这个库里面,这样你们问题是解决了,但是库还是有问题吧 |
现在库的所有人没有在维护了吧,好多pr都没有处理,我建议咱们fork一个,大家一起维护吧 |
场景: 问题: 解决方法: mPagingTouchSlop = conf.getScaledTouchSlop() * 2; 改成 mPagingTouchSlop = conf.getScaledTouchSlop(); 使 横滑 灵敏。 将 if (mDisableWhenHorizontalMove && !mPreventForHorizontal && (Math.abs(offsetX) > mPagingTouchSlop && Math.abs(offsetX) > Math.abs(offsetY))) {
if (mPtrIndicator.isInStartPosition()) {
mPreventForHorizontal = true;
}
}
if (mPreventForHorizontal) {
return dispatchTouchEventSupper(e);
} 改成 if (mDisableWhenHorizontalMove && (Math.abs(offsetX) > mHorizontalMoveSlop && Math.abs(offsetX) > Math.abs(offsetY))) {
mPreventForHorizontal = true;
}
if (mPreventForHorizontal) {
dispatchTouchEventSupper(e);
return true;
/*一旦横向滑动,就禁止竖向滑动,免得滑了一部分PtrFrameLayout将事件夺走 又开始竖向滑动了。因为大拇指向左滑动时的弧线垂直导数会越来越大 offsetY 可能会 大过 offsetX */
} 新增全局变量 之所以不用 TouchSlop 是因为 不同的手机上的 TouchSlop 大小不一样,改之后效果不一样,一加上的是 24,moto 上的 是 72 ,72对于横滑来说太大了,我都统一改小了。不同的手机上效果就一样了 感谢秋大 和 Aspsine 。 |
mPagingTouchSlop = conf.getScaledTouchSlop() * 2; 修改为 mPagingTouchSlop = conf.getScaledTouchSlop() recyclerview+viewpager 外套下拉刷新 改完后viewpager滑动好很多。 |
请问在WebView 的头部 有一个 banner 的时候导致, banner 左右滑动很容易触发下拉刷新, 这种 如何处理, 如何自己处理事件的分发, 自定义手指下滑距离和左右滑动距离来判断是下啦,还是滑动banner ? |
这个问题都这么久了,我感觉还是我的解决方案效果最好。 @yanzhenjie 你的这个方案是解决了左右滑的问题,但是下拉刷新变得非常不灵敏 #181 是我提交的PR |
感谢 @yanzhenjie 的解决方案,但你这个存在着下拉刷新不太灵敏,用户体验也不太好。我这里有个解决方案,在你这个基础上,添加HorizontalMoveView获取水平滑动的手势监听,当手势在HorizontalMoveView才进行拦截,这样就减少了其他区域的下拉事件的冲突,提高下拉刷新的灵敏。
PtrFrameLayout.java:
line 317:
各位有需要可以查看我的fork |
@lzyzsd 这个PR什么时候可以合并进去。。。这个issue还是挺严重的 |
@Lee-swifter 你的方法不推荐了,就算能解决VIEW PAGER的问题,也不适用于横向 recycle view。 |
我也遇到了这个问题,不过我的问题不复杂,退回1.0.9之后可以解决。但是我看了一下PtrFrameLayout的实现,有些粗浅看法: |
考虑重启一个项目,来完善这个库吧,作者已经没时间维护了吧 |
|
@yanzhenjie 使用你的方案后,下拉刷新变得很不灵敏了 |
PtrFrameLayout的dispatchTouchEvent方法实现没有考虑到requestDisallowInterceptTouchEvent,这样导致ViewPager不能通过requestDisallowInterceptTouchEvent解决PrtFrameLayout和ViewPager的事件冲突。
解决办法请看我的博客。http://dengyin2000.iteye.com/blog/2232210
The text was updated successfully, but these errors were encountered: