转载注明出处:http://blog.csdn.net/xiaohanluo/article/details/52130923
1. 前言
在Android开发中,如果是一些简单的布局,都很容易搞定,但是一旦涉及到复杂的页面,特别是为了兼容小屏手机而使用了ScrollView以后,就会出现很多点击事件的冲突,最经典的就是ScrollView中嵌套了ListView。我想大部分刚开始接触Android的同学们都踩到过这个坑,这一篇文章就从最近做的一个项目讲起,然后在过程中提供一些解决冲突的思路。
2. 项目起始
项目有一个页面,涉及到了ViewPager,MapView,ListView,也就是说在一个页面中,会有这三个View,很明显,屏幕无法完全显示,需要ScrollView来做一下支援,就引入了ScrollView作为外层的容器。但是由于这个页面的数据展示需要做到用户手动下拉刷新,于是又引入了官方的SwipeRefreshLayout。
于是这个页面的布局就成了这样子。如下图(细节布局忽略)。
图-1 布局图
加入了ScrollView和SwipeRefreshLayout之后引入了新的问题,就是各个控件之间的事件冲突,嵌套在ScrollView中的ViewPager、MapView、ListView都需要能够正确的处理点击事件,特别是ListView,需求要求它在ScrollView中可以滑动,两种滑动混淆在一起,不是特别好处理。
问题提出来了,下面直接看解决思路。
3. 解决滑动冲突的思路
在ViewGroup中有个方法叫requestDisallowInterceptTouchEvent(boolean disallowIntercept)
,这个方法可以用来控制该ViewGroup是否截断点击事件。我们解决滑动冲突的时候,其实就是在某个时机去调用这个方法,让父布局不截断点击事件,将点击事件传递到子View,让相关的子View去处理。
下面就是关于在项目中处理各种点击事件冲突的一些例子和思考。处理的方法只是提供一种思路,可能并不是最优的方法,肯定存在其他思路的解决方案。
以下处理滑动冲突的方案都是在子View的OnTouchListener里面进行处理,并没有去复写控件的点击事件处理过程,在使用中还是比较方便的。
3.1 MapView地图页面滑动冲突
MapView与ScrollView的冲突主要在于,当用户点击到MapView地图并且滑动的时候,希望由地图Map去处理点击事件,并包括后续的滑动事件、双手指缩放地图等等。
在ScrollView中,是会默认截断点击事件的,导致用户点击到地图后,地图基本是没有反应,更别谈双手指缩放地图了。
用户手指点击到地图,并且滑动的时候,很难确定用户是要ScrollView上下滑动还是操控地图内容滑动,所以我简单的认为,只要用户手指点击到地图,就是要对地图进行操作;当用户手指抬起,就认为用户不需要操作地图了。
解决思路也很简单,就是在用户点击到地图或者滑动地图时候,让ScrollView不截断点击事件,并传递给子View处理,也就是地图去处理点击事件;当用户手指抬起的时候,将ScrollView的状态恢复至之前的状态,也就是ScrollView可以截断点击事件。
我使用的是百度地图,直接上代码,更容易理解。
mMapView.getChildAt(0).setOnTouchListener(new View.OnTouchListener() {
@Override
public b