(源码分析)ScrollView嵌套ListView/GridView的滑动事件处理
来源:互联网 发布:win7 centos双系统 编辑:程序博客网 时间:2024/06/13 01:24
开发过程中经常会遇到使用scrollview嵌套listview或gridview的情况,这时由于scrollview拦截消费了滑动事件,所以在listview或gridview区域滑动时该区域无法滑动,而是scrollview整体滑动。
正确的处理应该是当焦点在listview或gridview区域该区域滑动,在区域外则scrollview滑动。
想要解决这个问题,加上如下代码即可:
listView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View arg0, MotionEvent arg1) { scrollView.requestDisallowInterceptTouchEvent(true);return false; } }
下面我们通过源码来看看requestDisallowInterceptTouchEvent是怎么起作用的。
requestDisallowInterceptTouchEvent函数实际上是ListView的父类AbsListView的一个函数,这个函数的源码如下:
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { if (disallowIntercept) { recycleVelocityTracker(); } super.requestDisallowInterceptTouchEvent(disallowIntercept);}
可以看到是调用了父类的同名函数,即ViewGroup的requestDisallowInterceptTouchEvent函数,源码如下:
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { if (disallowIntercept == ((mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0)) { // We're already in this state, assume our ancestors are too return; } if (disallowIntercept) { mGroupFlags |= FLAG_DISALLOW_INTERCEPT; } else { mGroupFlags &= ~FLAG_DISALLOW_INTERCEPT; } // Pass it up to our parent if (mParent != null) { mParent.requestDisallowInterceptTouchEvent(disallowIntercept); }}
其中mGroupFlags 保存的是二进制值,控制了几个开关。
在这里如果disallowIntercept为true的话,则为mGroupFlags添加FLAG_DISALLOW_INTERCEPT标志。同时如果有父view,调用父view的同名函数。因为父view也是ViewGroup,所以会一层层调用直到根布局。
那么FLAG_DISALLOW_INTERCEPT这个标志是如何影响滑动事件的呢?
这个标志使用在ViewGroup的dispatchTouchEvent函数中,由于代码较多,我们只截取有关的部分,如下:
// Check for interception.final boolean intercepted;if (actionMasked == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null) { final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0; if (!disallowIntercept) { intercepted = onInterceptTouchEvent(ev); ev.setAction(action); // restore action in case it was changed } else { intercepted = false; }} else { // There are no touch targets and this action is not an initial down // so this view group continues to intercept touches. intercepted = true;}
当mGroupFlags有FLAG_DISALLOW_INTERCEPT这个标志,则disallowIntercept为true,这时intercepted为false。
在dispatchTouchEvent函数的后续代码中intercepted为false则为所有的子view分发touch事件。
回到之前的问题中,当listview或gridview的区域touch时,设置requestDisallowInterceptTouchEvent为true,这样scrollview的touch就会分发下去,这样listview或gridview就可以响应滑动事件了。
阅读全文
0 0
- (源码分析)ScrollView嵌套ListView/GridView的滑动事件处理
- ScrollView嵌套GridView需要处理的事件
- ScrollView里嵌套ListView(或者gridview)时,内部控件滑动时外部控件也会动的异常处理
- android ListView/GridView与ScrollView嵌套的滑动冲突解决
- scrollview嵌套listview 滑动事件冲突的解决方法
- Android scrollview嵌套listview 滑动事件冲突的解决方法
- ScrollView中嵌套ListView或者GridView时的滑动冲突 || ListView中嵌套GridView,GridView只显示一行的问题解决
- ScrollView嵌套GridView、ListView
- ScrollView嵌套ListView、GridView
- ScrollView 嵌套 ListView GridView
- ScrollView嵌套ListView处理事件冲突
- ScrollView中嵌套ListView与GridView时滑动冲突解决方案
- ScrollView嵌套GridView、ListView的解决办法
- ScrollView嵌套GridView、ListView的解决办法
- ScrollView嵌套GridView、ListView的解决办法
- ScrollView嵌套GridView、ListView的解决办法
- ScrollView中嵌套GridView,Listview的办法
- ScrollView中嵌套GridView,Listview的办法
- 三次握手,四次挥手简介
- 二叉堆及其在A*算法中的应用
- 普及练习场 贪心 纪念品分组
- Java反射机制浅谈
- Java基础系列 -- 集合篇
- (源码分析)ScrollView嵌套ListView/GridView的滑动事件处理
- arm GDB
- Linux多进程中的fork与vfork
- jar和aar在Android Studio中的生成和使用
- 极客物联网 远程开关 入门示例
- 在windows环境下测试nginx+rtmp流媒体服务器连接数
- ImportError: No module named 'bs4'
- 构建高并发高可用的电商平台架构实践
- 白话C++系列(this指针)