Android滑动冲突的完美解决

所属分类: 软件编程 / Android 阅读数: 44
收藏 0 赞 0 分享

Android滑动在智能手机上是必备的操作,但是在开发的时候,你是否和我一样,经常会遇到滑动冲突的问题,比如最简单需要在ListView里面添加一个侧滑动作,这时候冲突时必然的,那我们该如何解决这个问题呢?
先来说一下滑动冲突都有那些,该怎么解决。

场景一:类似于ViewPager嵌套Fragmnet并且在Fragmnet中嵌套了一个ListView的效果,可以通过左右滑动来切换或者触发其他view的显示。但是在ViewPager内部已经处理了这个冲突,所以我们会发现ViewPager嵌套Fragmnet的时候很是流畅。如果我们采用的不是ViewPager而是ScrollView,那么就需要我们主动去处理这个冲突了;
场景二:这种情况比较复杂,那就是view和被嵌套的view需要在同一个方向上滑动,这时候,用户滑动view的时候,系统就不知道用户想要滑动的view是哪一个,问题就不由自主的跳出来了;
场景三:场景三是最为复杂的一种,即有场景一的情况,也有场景二的情况,两种情况的叠加,所以需要处理内部和中部、中部和和外部的冲突。

问题已经出来了,那我们怎么解决呢?

view既然可以滑动,那么就有滑动的规律,一般来说,当用户滑动时,需要让外部的view拦截点击事件,当用户上下滑动时,需要让内部view拦截view的点击事件,这时候,我们就可以根据是上下还是左右滑动来具体处理冲突事件。对于场景二和场景三,大致的想法也是差不多的,修改相关的滑动规则就OK了。

1、外部拦截:

所谓的外部拦截是指点击事件都先经过父容器的拦截处理,如果有需要就去拦截,否则不拦截,这样就可以简单的处理场景一的问题了。

public boolean onInterceptTouchEvent(MotionEvent event){
 boolean intercepted=false;
 int x=(int)event.getX();
 int y=(int)event.getY();
 switch(event.getAction()){
 case MotionEvent.ACTION_DOWN:
  break;
 case MotionEvent.ACTION_MOVE:
  if(父容器需要当前点击事件){
  intercepted=true;
  }else{
  intercepted=false;
  }
  break;
 case MotionEvent.ACTION_UP:
  intercepted=false;
  break;
 default:
  break; 
 }
 mLastXIntercepted=x;
 mLastYIntercepted=y;
 return intercepted;
}

上面的代码是最基础的外部拦截逻辑,针对不同的情况,修改父容器需要的条件即可。当点击view和释放view的时候,我们不需要处理滑动操作,只需要当拖动view的时候,需要去拦截就OK了。

2、内部拦截:

内部拦截和外部拦截正好相反,指的是所有的事件都传递给子view来处理,如果需要,子view直接消费掉,否则不消费。这里消费是指子view处理掉父容器传递过来的事件。这种方法需要配合requestDisallowInterceptedTouchEvent方法才行:

public boolean dispatchTouchEvent(MotionEvent event){
 int x=(int)event.getX();
 int y=(int)event.getY();

 switch(event.getAction()){
 case MotionEvent.ACTION_DOWN:
  parent.requestDisallowInterceptedTouchEvent(true);
  break;
 case MotionEvent.ACTION_MOVE:
  int deltaX=x-mLastX;
  int deltaY=y-mLastY;
  if(父容器需要点击事件){
  parent.requestDisallowInterceptedTouchEvent(false);
  }
  break;
 case MotionEvent.ACTION_UP:
  intercepted=false;
  break;
 default:
  break; 
 }
 mLastX=x;
 mLastY=y;
 return super.dispatchTouchEvent(event);
}

子view除了需要处理以外,父容器默认拦截除了按下事件以外的所有事件,这样才能让子view调用requestDisallowInterceptedTouchEvent方法时,父容器继续去拦截其他事件。这是典型的内部拦截处理方案。在这里你可能很疑惑,为什么父容器不能拦截ACTION_DOWN事件呢?那是因为ACTION_DOWN事件不受FLAG_DISALLOW_INTERCEPT这个标记的控制,如果父容器拦截ACTION_DOWN事件,那么所有的事件都不可能传递给子view了,这样的拦截根本就不能达到我们的目的。

至于场景三的解决方案,根据情况不同,微调方案一和方案二即可。

解决滑动冲突的方案就这么多,而开篇提到的问题,显然是可以使用方案一来解决的。

更多精彩内容其他人还在看

Android网络编程之获取网络上的Json数据实例

这篇文章主要介绍了Android网络编程之获取网络上的Json数据实例,本文用完整的代码实例讲解了在Android中读取网络中Json数据的方法,需要的朋友可以参考下
收藏 0 赞 0 分享

Android中的windowSoftInputMode属性详解

这篇文章主要介绍了Android中的windowSoftInputMode属性详解,本文对windowSoftInputMode的9个属性做了详细总结,需要的朋友可以参考下
收藏 0 赞 0 分享

Android网络编程之UDP通信模型实例

这篇文章主要介绍了Android网络编程之UDP通信模型实例,本文给出了服务端代码和客户端代码,需要的朋友可以参考下
收藏 0 赞 0 分享

Android中使用ListView实现漂亮的表格效果

这篇文章主要介绍了Android中使用ListView实现漂亮的表格效果,本文用详细的代码实例创建了一个股票行情表格,需要的朋友可以参考下
收藏 0 赞 0 分享

Android中刷新界面的二种方法

这篇文章主要介绍了Android中刷新界面的二种方法,本文使用Handler、postInvalidate两种方法实现界面刷新,需要的朋友可以参考下
收藏 0 赞 0 分享

Android SDK三种更新失败及其解决方法

这篇文章主要介绍了Android SDK三种更新失败及其解决方法,需要的朋友可以参考下
收藏 0 赞 0 分享

Android学习笔记——Menu介绍(一)

Android3.0(API level 11)开始,Android设备不再需要专门的菜单键。随着这种变化,Android app应该取消对传统6项菜单的依赖。取而代之的是提供anction bar来提供基本的用户功能
收藏 0 赞 0 分享

Android学习笔记——Menu介绍(二)

这次将继续上一篇文章没有讲完的Menu的学习,上下文菜单(Context menu)和弹出菜单(Popup menu)
收藏 0 赞 0 分享

Android学习笔记——Menu介绍(三)

今天继续昨天没有讲完的Menu的学习,主要是Popup Menu的学习,需要的朋友可以参考下
收藏 0 赞 0 分享

Android显示网络图片实例

这篇文章主要介绍了Android显示网络图片的方法,以实例形式展示了Android程序显示网络图片的方法,非常具有实用价值,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多