如何禁止内部viewPager滑动
众所周知,viewPager是能够滑动的,但有时候我们需要禁止它的滑动(微笑地面对*—……—*)。
情况是这样的:
activity中有一个viewPager,viewPager中加入3个Fragment,第三个Fragment中又使用了一个viewPager,这个viewPager中又加入了几个Fragment(本人不是受虐狂,仅仅是功能需要)。如图:



想实现的功能:
点击activity的图标或者滑动的时候能够切换第一个viewPager中的Fragment,点击Fragment3中的图标能够切换第二个viewPager里的Fragment,但是禁止这个viewPager滑动,第二个viewPager里的Fragment1里面有一个listView(有下拉刷新功能),要能够上下滑动不受影响。
关键就是禁止内部viewPager滑动,但是其它的功能不受影响。
呵呵,已经元气大伤......
探索过程已经不想吐槽。
这个问题涉及到事件的分发机制,需要重写viewPager。那么到底该重写哪个viewPager呢?
首先分析一下这个问题的解决过程:
1.要禁止里面的viewPager左右滑动,那么即是说当我们左右滑动的时候,外面的viewPager要拦截事件,当我们上下滑动的时候外面的viewPager不能拦截事件,这样事件才能传递到内部的viewPager,内部viewPager里的fragment包含的listView才能上下滑动。
2.当然点击事件也不能够拦截,这样点击Fragment3的图标才能切换内部viewPager里面的Fragment。
3.由于内部viewPager在Fragment3,所以我们在外部的viewPager切换到item3的时候再做1,2步的处理。
在这里重写外部viewPager会比较方便,即我们用外部拦截法。
接下来请看外部拦截神功。
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import neo.door.usermanager.UserManager; public class MyViewPager extends ViewPager {
private int mFirstX =0,mFirstY=0;
private String TAG = "MyViewPager"; public MyViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
} @Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if(this.getCurrentItem()==2) //如果滑动到了第三个Fragment
{
boolean isIntercept=false;
int x=(int) event.getX();
int y=(int) event.getY();
Log.e(TAG, "onInterceptTouchEvent");
switch (event.getAction()) {
/**
* 父容器必须返回false,即不拦截ACTION_DOWN事件,
* 否则后续的ACTION_MOVE,ACTION_UP事件都会直接交给父容器处理,
* 事件没办法再传递给子元素了
*/
case MotionEvent.ACTION_DOWN:
Log.e(TAG, "onInterceptTouchEvent_ACTION_DOWN");
isIntercept=false;
break;
/**
* 根据需要觉定是否拦截
*/
case MotionEvent.ACTION_MOVE: if (Math.abs(x - mFirstX) > Math.abs(y - mFirstY)) //左右滑动
{
isIntercept = true;
if(正在下拉) //想刷新时候(若不写这一步,如果我们向下滑到一半突然左右滑动那么listView就会卡在中间状态不动。)
isIntercept=false;
}
else //上下滑动
{
isIntercept = false;
}
Log.e(TAG, "onInterceptTouchEvent_ACTION_MOVE");
break;
/**
* 必须返回false,因为ACTION_UP本身没有太大意义。
*
*/
case MotionEvent.ACTION_UP:
isIntercept=false;
Log.e(TAG, "onInterceptTouchEvent_ACTION_UP");
break;
default:
break;
} mFirstX=x;
mFirstY=y;
Log.e(TAG, "onInterceptTouchEvent_return");
return isIntercept;
}
else //如果没有滑动到了第三个Fragment,不作处理
return super.onInterceptTouchEvent(event);
}
}
首先要知道 onInterceptTouchEvent这个方法,返回true代表拦截,返回false代表不拦截。
注意:
1.ACTION_UP。
考虑一种情况:若是事件交给子元素处理,而父容器在ACTION_UP的时候返回了true,那么子元素就会无法收到ACTION_UP事件,子元素的onClik事件无法触发,也就是说在这道题中,Fragment3的图标将无法点击,并且listView的滑动会在手指离开屏幕的时候停留在中间态。
父容器比较特殊,一旦它开始拦截任何一个事件,那么后续事件都会交给它处理,ACTION_UP作为最后一个事件也一样可以传递给父容器,即便父容器的onInterceptTouchEvent方法在ACTION_UP时返回了false。
2.ACTION_MOVE之中。
假如我们要刷新listView,在我们下拉listView的时候手指突然间左滑或者右滑,那么listView就会停留在中间状态。放开手也不会回去,为什么呢?
原因是这样的:在我们手指下滑的时候,在ACTION_MOVE中判断后不符合 (Math.abs(x - mFirstX) > Math.abs(y - mFirstY)),所以父容器即外部的viewPager返回false,不拦截事件,listView能够滑动。但是当我们在下滑的时候突然间左右滑,那么在ACTION_MOVE中判断后符合 (Math.abs(x - mFirstX) > Math.abs(y - mFirstY)),所以父容器即外部的viewPager返回true,拦截了事件,所以listView无法完成事件,只是停留在了手指左右滑动之前的那个瞬间状态。(这种情况最后的ACTION_UP没有执行,这点还不理解)
所以我们要加个判断,判断listview是否正要下拉刷新,如果是,不要拦截事件。
至于判断方法挺多的,就不再写。
【写到这里,也就差不多了,以后若是有得补充再来补充吧。@—^—@】
如何禁止内部viewPager滑动的更多相关文章
- android 禁止ViewPager滑动
最近项目中,有个需求就是要禁止ViewPager滑动事件,我们看下360手机助手的界面,风格就类似这样的 大家如果使用过360手机助手就会发现中间内容是不可以滑动的,现在写一个demo,讲下怎么禁止V ...
- (转)ViewPager,ScrollView 嵌套ViewPager滑动冲突解决
ViewPager,ScrollView 嵌套ViewPager滑动冲突解决 本篇主要讲解一下几个问题 粗略地介绍一下View的事件分发机制 解决事件滑动冲突的思路及方法 ScrollView 里面嵌 ...
- 重写ListView解决ListView内部ViewPaper滑动事件冲突问题
非常easy 重写ListView 其它类似问题解决ScrollView嵌套ViewPager出现的滑动冲突问题 http://blog.csdn.net/zhangyiacm/article/det ...
- ViewPager 滑动页(四)
需求:在ViewPager 滑动页(三) 基础上,减少界面层级. 效果图: 图层数变更前: 图层数变更后: 主要代码实现: <?xml version="1.0" encod ...
- 【解决ViewPager在大屏上滑动不流畅】 设置ViewPager滑动翻页距离
在项目中做了一个ViewPager+Fragment滑动翻页的效果,在模拟器和小米手机上测试也比较正常.但是换到4.7以上屏幕测试的时候发现老是滑动失效. 因为系统默认的滑动策略是当用户滑动超过半屏之 ...
- ViewPager滑动后,可移动的Imageview会回到初始化的位置
知乎看到的原文http://www.zhihu.com/question/37398770?sort=created ViewPager滑动后,可移动的Imageview会回到初始化的位置? < ...
- Flutter - ListView禁止用户上下滑动
ListView禁止用户上下滑动可以使用physics属性 physics: const NeverScrollableScrollPhysics()
- android开发学习之ViewPager滑动事件讲解
android ViewPager滑动事件讲解 今天在做项目的时候,由于要处理viewPager页面滑动的事件,所以对其进行了一个小小的研究: 首先ViewPager在处理滑动事件的时候要用到OnPa ...
- PullToRefreshListView中嵌套ViewPager滑动冲突的解决
PullToRefreshListView中嵌套ViewPager滑动冲突的解决 最近恰好遇到PullToRefreshListView中需要嵌套ViewPager的情况,ViewPager 作为头部 ...
随机推荐
- .NET全栈开发工程师学习路径
PS:最近一直反复地看博客园以前发布的一条.NET全栈开发工程师的招聘启事,觉得这是我看过最有创意也最朴实的一个招聘启事,更为重要的是它更像是一个技术提纲,能够指引我们的学习和提升,现在转载过来与各位 ...
- 设置Fn键 笔记本直接按F1-F12 无须按Fn键 Fn+F12改F12(联想小新300为例)
最近公司给配的笔记本联想小新300 80RT i7-6500U 4G内存 500G机械,后加装120G固态+4G内存 这样就感觉还不错了. 在使用这本子的时候,去了Win10,强行装了Win7.无线 ...
- (转载)解决“Windows Update一直无法完成”的方法
近日彻底重装系统,启动Win7的"Windows Update",程序显示在检查更新,却一直没有结果. 在排除网络问题,排除杀毒软件和防火墙的问题之后,感觉还是程序或者配置除了问题 ...
- css中常见的属性-----在路上(14)
一.css文字属性 color : #999999; /*文字颜色*/ font-family : 宋体,sans-serif; /*文字字体*/ font-size : 9pt; /*文字大小*/ ...
- javascript中的Function和Object
写的很好,理解了很多,特此转发记录 转自:http://blog.csdn.net/tom_221x/archive/2010/02/22/5316675.aspx 在JavaScript中所有的对象 ...
- lr文件下载脚本(文件参数化重命名)
http://wenku.baidu.com/link?url=6oiIadyF9eFS4VshKbfJDnxrBh2IX919ndi0JO8yoqTRNRNIpavFrZJ9LPVb-FBSfbRY ...
- backup4:数据库自动备份,自动删除备份文件
一:手写TSQL 脚本 1,自动备份 每周进行一次Database 的 Full Backup,设置 Schedule Interval 为Weekly use master go ) )+N'.ba ...
- HTML自定义对象与属性(谷歌,火狐,IE9浏览器没问题)
1.自定义标签 <zqz>asdas</zqz> <style> zqz{ color:red; } </style> 页面变色 2.自定义标签的hov ...
- JS中 call() 与apply 方法
1.方法定义 call方法: 语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象. 说明: call ...
- SQL Server-聚焦过滤索引提高查询性能(十)
前言 这一节我们还是继续讲讲索引知识,前面我们讲了聚集索引.非聚集索引以及覆盖索引等,在这其中还有一个过滤索引,通过索引过滤我们也能提高查询性能,简短的内容,深入的理解,Always to revie ...