`

【转】Android滑屏与子控件点击事件处理

 
阅读更多

转自:http://blog.csdn.net/tomatozq/article/details/44564889

想象下面画面描述中的情况,程序如何区分当前用户是想打开程序还是滑动界面?


    在android中,触摸屏幕事件逻辑如下:

1.首先调用父容器的onInterceptTouchEvent方法。

2.如果该方法返回true,则说明该触屏事件被父容器拦截,触屏事件不会传递到子控件中去处理,直接调用容器的onTouchEvent方法。

3. 如果该方法返回false,则将触屏事件传递到子控件中去处理,如果子控件在onTouchEvent方法返回true,则说明触屏事件已被消费,不会再 传递给父容器;如果子控件的onTouchEvent方法返回false,则再调用父容器的onTouchEvent处理。

4. 触屏事件一般有三个阶段ACTION_DOWN、ACTION_MOVE、ACTION_UP,在onInterceptTouchEvent方法和 onTouchEvent方法中,都可以对着三个阶段进行处理。如果父容器在onInterceptTouchEvent某一阶段返回false,则系统 会在后续阶段再次调用onInterceptTouchEvent。

    现在回到程序如何区分当前用户是想打开程序还是滑动界面的问题上,滑动界面和点击图标只有在ACTION_MOVE阶段中才能区分,子控件如果是可点击 的,则子控件的OnTouchEvent一定会返回true,也就是说如果触屏事件将ACTION_DOWN和ACTION_UP事件都传递给子控件,当 前动作就变成了点击图标,所以判断当前是滑动还是点击就必须在onInterceptTouchEvent方法中处理。

    首先在onInterceptTouchEvent的ACTION_DOWN阶段,无法判断是否滑动还是点击,则需要返回false,以便后续阶段中调用拦截事件。

    然后系统会进入onInterceptTouchEvent的ACTION_MOVE阶段,在当前阶段可以用触摸移动的距离来判断是点击还是滑动。

    判读移动距离是否大于ViewConfiguration.get(getContext()).getScaledTouchSlop(),就可以判断 是点击还是滑动,如果是点击则直接返回false,交给子控件处理;如果是滑动则返回true,然后系统就会调用容器的onTouchEvent其中 action是为ACTION_MOVE,只需要在这里处理滑动的具体代码即可。

    如果在onInterceptTouchEvent的ACTION_MOVE阶段返回true(滑动屏幕),则不会在进入 onInterceptTouchEvent的ACTION_UP阶段了,系统会直接调用onTouchEvent的ACTION_UP阶段,所以处理滑 屏的惯性效果就在这里处理。

    如果在onInterceptTouchEvent的ACTION_MOVE阶段返回false(点击图标),则系统会进入 onInterceptTouchEvent的ACTION_UP阶段,此时需要传递false,以便子控件接收ACTION_UP,完成点击事件。

 

  1. /** 
  2.  * 是否传递到子view 
  3.  * true  不传递 
  4.  * false 传递 
  5.  * 一次触摸屏幕中,如果拦截过则不会再次进入onInterceptTouchEvent 
  6.  * 触摸屏幕中,如果在ACTION_DOWN时返回true,则不会再有ACTION_MOVE和ACTION_UP拦截 
  7.  * 如果ACTION_DOWN返回false,ACTION_MOVE中返回true,则不会有ACTION_UP拦截 
  8.  */  
  9. @Override  
  10. public boolean onInterceptTouchEvent(MotionEvent event) {  
  11.     // TODO Auto-generated method stub  
  12.     switch(event.getAction()){  
  13.         case MotionEvent.ACTION_DOWN:  
  14.             //如果ACTION_DOWN未被拦截,则有可能被子view消费,一旦消费后,  
  15.             //则父容器中OnTouchEvent中就不会接受到ACTION_DOWN事件  
  16.             System.out.println("onInterceptTouchEvent ACTION_DOWN");  
  17.             touchDownX = event.getX();  
  18.             startX = this.getScrollX();  
  19.                               
  20.             mScrolling = false;  
  21.               
  22.             velocityTracker = VelocityTracker.obtain();  
  23.               
  24.             velocityTracker.addMovement(event);  
  25.             break;  
  26.         case MotionEvent.ACTION_MOVE:  
  27.             System.out.println("onInterceptTouchEvent ACTION_MOVE");  
  28.               
  29.             if(Math.abs(touchDownX - event.getX())>=mTouchSlop){  
  30.                 mScrolling = true;  
  31.             }  
  32.             else{  
  33.                 mScrolling = false;  
  34.             }  
  35.               
  36.             break;  
  37.         case MotionEvent.ACTION_UP:  
  38.             //如果ACTION_MOVE判断是点击就会进入ACTION_UP,是滚动则不会进入  
  39.             System.out.println("onInterceptTouchEvent ACTION_UP");    
  40.               
  41.             //返回false以便子控件接收ACTION_UP事件  
  42.             mScrolling = false;   
  43.               
  44.             break;  
  45.     }  
  46.       
  47.     return mScrolling;  
  48. }  
  49.   
  50. /** 
  51.  * onTouchEvent() 用于处理事件,返回值决定当前控件是否消费(consume)了这个事件。 
  52.  * 可能你要问是否消费了又区别吗,反正我已经针对事件编写了处理代码? 
  53.  * 答案是有区别!比如ACTION_MOVE或者ACTION_UP发生的前提是一定曾经发生了ACTION_DOWN, 
  54.  * 如果你没有消费ACTION_DOWN,那么系统会认为ACTION_DOWN没有发生过, 
  55.  * 所以ACTION_MOVE或者ACTION_UP就不能被捕获。 
  56.  * */  
  57. @Override  
  58. public boolean onTouchEvent(MotionEvent event) {  
  59.     // TODO Auto-generated method stub  
  60.     switch(event.getAction()){  
  61.         case MotionEvent.ACTION_DOWN:  
  62.             System.out.println("ACTION_DOWN");                
  63.             break;  
  64.         case MotionEvent.ACTION_MOVE:  
  65.             System.out.println("ACTION_MOVE");  
  66.             int offsetX = Float.valueOf(startX + touchDownX - event.getX() ).intValue();  
  67.               
  68.             if (offsetX>=0 && offsetX<=this.getWidth()) {  
  69.                 scrollTo(offsetX,0);  
  70.             }  
  71.   
  72.             velocityTracker.addMovement(event);  
  73.               
  74.             break;  
  75.         case MotionEvent.ACTION_UP:  
  76.             System.out.println("ACTION_UP");  
  77.               
  78.             velocityTracker.computeCurrentVelocity(500);  
  79.               
  80.             //从左往右,velocity>0,实际是想往回拔  
  81.             int speed = -Float.valueOf(velocityTracker.getXVelocity()).intValue();  
  82.               
  83.             System.out.println("scrollX:" + this.getScrollX() + ",speed:" + speed);  
  84.               
  85.             //开始滚动->起始点,偏移距离,持续事件  
  86.             mScroller.startScroll(this.getScrollX(), 0,speed, 0,2000);  
  87.             velocityTracker.recycle();  
  88.             break;  
  89.         default:  
  90.             break;  
  91.     }  
  92.       
  93.     return true;  

分享到:
评论

相关推荐

    Android 滑屏控件

    网上下载的,自己略有修改和完善。懂行的人一般都会喜欢。报错的地方请注释掉即可。

    android中实现滑屏三种方法

    本文将详细介绍三种实现Android滑屏效果的方法:使用ViewPager、GestureDetector和自定义View。 1. **ViewPager** ViewPager是Android SDK中的一个控件,主要用于在多个页面间进行左右滑动切换。它可以自动处理...

    Android滑屏及相关效果Demo

    【Android滑屏及相关效果Demo】是一个面向初学者的实践项目,旨在帮助理解并掌握...通过深入研究和实践,开发者不仅可以掌握滑动界面的实现,还能进一步理解Android的事件处理机制、数据绑定以及性能优化等关键知识点。

    APP滑屏容器控件(Delphi)

    滑屏容器控件(FMXSliderContainer)是专为手机APP程序界面变换或图片浏览等支持滑屏操作提供的一种解决方案,该控件纯Delphi原生代码设计开发,无需其他任何第三方控件,通过该控件,能够很方便的使APP程序具有横向...

    上下滑屏控件

    总之,上下滑屏控件的实现涉及到Android视图的基础知识,包括触摸事件处理、自定义布局以及性能优化。通过自定义`VerticalScrollLayout`,开发者可以根据具体需求定制滑动行为,打造个性化的用户体验。对于深入学习...

    滑屏切换界面

    首先,滑屏切换界面的基础是触摸事件处理。Android系统提供了`MotionEvent`类,用于处理用户在屏幕上的一系列触摸动作。当用户进行滑动操作时,系统会连续发送`ACTION_DOWN`(触摸开始)、`ACTION_MOVE`(触摸移动)...

    android 滑屏

    在滑屏场景中,我们可以通过重写`onInterceptTouchEvent()`和`onTouchEvent()`这两个方法来捕获和处理触摸事件,实现屏幕滑动的效果。`onInterceptTouchEvent()`用于拦截子View的触摸事件,而`onTouchEvent()`则处理...

    android实现随手指拖动滑屏

    本文将深入探讨如何在Android应用中实现这一功能,主要涉及的技术点包括触摸事件处理、布局管理以及可能用到的控件如TabHost。 首先,我们要理解Android中的触摸事件处理机制。Android通过MotionEvent类来封装触摸...

    android滑屏

    总结,实现Android滑屏功能有多种方法,包括使用FragmentTransaction动画、ViewPager和手势检测等。开发者可以根据项目需求选择合适的方法,为用户提供流畅、直观的滑动体验。在实际开发过程中,记得进行充分的测试...

    Android ViewFlipper左右自动滑屏 源码

    在Android开发中,ViewFlipper是一个非常有用的布局控件,它可以轻松实现多个视图之间的切换,比如我们在很多应用中看到的广告轮播效果。本文将深入讲解如何利用ViewFlipper实现左右自动滑屏功能,并结合源码分析其...

    android中左右滑屏的实现

    总的来说,实现Android中的左右滑屏功能,主要是通过合理使用ViewPager及其适配器,结合可能的SwipeRefreshLayout,配合监听事件和自定义逻辑来完成。这不仅是Android开发的基本技能,也是提升用户体验的关键点。...

    android 左右滑屏

    总之,Android左右滑屏涉及到了Android的基础控件使用、自定义布局和触摸事件处理等多方面知识。通过理解并熟练运用这些知识点,开发者能够构建出流畅、自然的用户界面,提升应用的用户体验。在实际项目中,根据需求...

    android左右滑屏

    首先,我们要理解Android的触摸事件处理机制。Android中的触摸事件主要由`MotionEvent`类来表示,开发者可以通过重写`Activity`或`View`的`onTouchEvent()`方法来捕获并处理这些事件。当用户在屏幕上进行滑动操作时...

    huaping.zip_android_huaping.zip

    总的来说,"huaping.zip"项目展示了Java在Android滑屏应用开发中的应用,涉及到了Android手势识别、UI构建和事件处理等多个重要知识点。要深入理解并复现这个项目,需要熟悉Android开发环境,掌握Java编程基础,以及...

    android滑动广告

    `ViewPager`是Android SDK中的一个强大的控件,它用于展示可滑动的页面集合。在滑动广告场景中,`ViewPager`扮演着核心角色。它可以自动处理页面的滑动效果,使用户能够左右滑动查看不同的广告内容。`ViewPager`通过...

    Android ActivtiyGroup和ViewFlipper实现Activity滑屏切换

    `GestureDetector`是一个监听触摸事件的工具类,它可以识别各种手势,如滑动、点击等。首先,你需要创建一个`GestureDetector`的实例,并实现`OnGestureListener`接口。在`onTouchEvent()`方法中,传递触摸事件给`...

    Android-app.rar

    Android仿微博、微信、qq 点击缩略图TransferImage Android例子源码IOS风格的uitableview列表 Android例子源码IOS风格的圆角分组设置页面 Android例子源码不断保持后台唤醒的例子源码 Android例子源码九宫格密码输入...

    TextFragment标签滑屏效果

    在Android应用开发中,创建一个动态且交互性强的用户界面是至关重要的,而"TextFragment标签滑屏效果"就是一种常见的UI设计模式,用于展示可滑动切换的标签页。这种效果常见于许多应用程序,如新闻阅读器、音乐...

    滑屏Demo(随手指拖动)

    7. **触摸事件处理**:滑屏Demo可能覆盖了默认的触摸事件处理,以便在用户手指按下、移动和释放时做出相应的响应。通过重写onTouchEvent()方法,可以精确地控制滑动行为。 综上所述,滑屏Demo的实现涉及到了Android...

    安卓开发ViewPager与Layout实现滑屏

    在这个项目中,我们将深入探讨如何使用ViewPager与不同的Layout来实现滑屏功能。 首先,ViewPager是Android Support Library中的一个控件,它扩展自ViewGroup,主要用于展示一系列的页面,每个页面都可以有自己的...

Global site tag (gtag.js) - Google Analytics