Android判断Touch为滑动事件还是操作控件

因为在项目中要判断WebView是否处于滚动状态,但它不像ListView有onScrollStateChanged方法来监听,要实现就得手动监听它的Touch事件。

谈起Touch事件不得说提到 onInterceptTouchEvent,它是ViewGroup的一个扩展函数,要实现高级效果 必不可少的就需要重写 onInterceptTouchEvent、对所有的 MotionEvent 起到一个过滤的作用,最终的目的是防止一些事件传递到它包含的子控件中。

以ScrollView为例介绍滑动滚动条的判定。

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    /*
     * This method JUST determines whether we want to intercept the motion.
     * If we return true, onMotionEvent will be called and we do the actual
     * scrolling there.
     */
    /*
    * Shortcut the most recurring case: the user is in the dragging
    * state and he is moving his finger.  We want to intercept this
    * motion.
    */
    final int action = ev.getAction();
    if ((action == MotionEvent.ACTION_MOVE) && (mIsBeingDragged)) {
        return true;
    }
    switch (action & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_MOVE: {
            /*
             * mIsBeingDragged == false, otherwise the shortcut would have caught it. Check
             * whether the user has moved far enough from his original down touch.
             */
            /*
            * Locally do absolute value. mLastMotionY is set to the y value
            * of the down event.
            */
            final int activePointerId = mActivePointerId;
            if (activePointerId == INVALID_POINTER) {
                // If we don't have a valid id, the touch down wasn't on content.
                break;
            }
            //通过activePointerId 的值来获得 当前 触摸点的索引
            final int pointerIndex = ev.findPointerIndex(activePointerId);
            //通过索引的值获得当前触摸的y的值
            final float y = ev.getY(pointerIndex);
            final int yDiff = (int) Math.abs(y - mLastMotionY);
            //根据绝对值和零界点来判断是单击还是滑动滚动条
            if (yDiff > mTouchSlop) {
                mIsBeingDragged = true;
                mLastMotionY = y;
                initVelocityTrackerIfNotExists();
                mVelocityTracker.addMovement(ev);
                if (mScrollStrictSpan == null) {
                    mScrollStrictSpan = StrictMode.enterCriticalSpan("ScrollView-scroll");
                }
            }
            break;
        }
        case MotionEvent.ACTION_DOWN: {
            final float y = ev.getY();
            if (!inChild((int) ev.getX(), (int) y)) {
                mIsBeingDragged = false;
                recycleVelocityTracker();
                break;
            }
            /*
             * Remember location of down touch.
             * ACTION_DOWN always refers to pointer index 0.
             */
              //记录 mLastMotionY  和 mActivePointerId
            //在 MotionEvent.ACTION_MOVE 状态时会用到
            mLastMotionY = y;
            mActivePointerId = ev.getPointerId(0);
            initOrResetVelocityTracker();
            mVelocityTracker.addMovement(ev);
            /*
            * If being flinged and user touches the screen, initiate drag;
            * otherwise don't.  mScroller.isFinished should be false when
            * being flinged.
            */
            mIsBeingDragged = !mScroller.isFinished();
            if (mIsBeingDragged && mScrollStrictSpan == null) {
                mScrollStrictSpan = StrictMode.enterCriticalSpan("ScrollView-scroll");
            }
            break;
        }
        case MotionEvent.ACTION_CANCEL:
        case MotionEvent.ACTION_UP:
            /* Release the drag */
            mIsBeingDragged = false;
            mActivePointerId = INVALID_POINTER;
            recycleVelocityTracker();
            if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange())) {
                invalidate();
            }
            break;
        case MotionEvent.ACTION_POINTER_UP:
            onSecondaryPointerUp(ev);
            break;
    }
    /*
    * The only time we want to intercept motion events is if we are in the
    * drag mode.
    */
    return mIsBeingDragged;
}

Android判断Touch为滑动事件还是操作控件的更多相关文章

  1. Android 自定义简易的方向盘操作控件

    最近在做一款交互性较为复杂的APP,需要开发一个方向操作控件.最终用自定义控件做了一个简单的版本. 这里我准备了两张素材图,作为方向盘被点击和没被点击的背景图.下面看看自定义的Wheel类 publi ...

  2. (转载) Android RecyclerView 使用完全解析 体验艺术般的控件

    Android RecyclerView 使用完全解析 体验艺术般的控件 标签: Recyclerviewpager瀑布流 2015-04-16 09:07 721474人阅读 评论(458) 收藏  ...

  3. 怎样在Android实现桌面清理内存简单Widget小控件

    怎样在Android实现桌面清理内存简单Widget小控件 我们常常会看到类似于360.金山手机卫士一类的软件会带一个widget小控件,显示在桌面上,上面会显示现有内存大小,然后会带一个按键功能来一 ...

  4. winform 跨线程操作控件

    当进行winform的开发时,经常遇到用时比较久的操作,在传统的单线程程序中,用户必须等待这个耗时操作完成以后才能进行下一步的操作,这个时候,多线程编程就派上用场了,将这个耗时的操作放到一个新的子线程 ...

  5. ANDROID L——Material Design详解(UI控件)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! Android L: Google已经确认Android L就是Android Lolli ...

  6. WinForm中跨线程操作控件

    在WinForm编程时会遇到通过后台线程操作界面的情况,直接在后台线程执行的方法中直接操作控件会报错,这时候就要使用跨线程方式间接操作控件.下面是两种实现方式.   1.采用定义delegate的方式 ...

  7. C# 跨线程操作控件(简洁)

                                              C# 跨线程操作控件 .net 原则上禁止跨线程访问控件,因为这样可能造成错误的发生.解决此问题的方法有两个: 第一 ...

  8. Winform跨窗体操作控件(使用委托)

    Winform跨窗体操作控件是winform开发中很常见的形式,最常见且简单有效的方式便是使用委托的方式来进行操作,下面我将通过一个小实例来说明如何使用委托跨窗体实现控件操作. 实例介绍:两个窗体,F ...

  9. Android 打造完美的侧滑菜单/侧滑View控件

    概述 Android 打造完美的侧滑菜单/侧滑View控件,完全自定义实现,支持左右两个方向弹出,代码高度简洁流畅,兼容性高,控件实用方便. 详细 代码下载:http://www.demodashi. ...

随机推荐

  1. ExtJs4 笔记(14) layout 布局

    作者:李盼(Lipan)出处:[Lipan] (http://www.cnblogs.com/lipan/)版权声明:本文的版权归作者与博客园共有.转载时须注明本文的详细链接,否则作者将保留追究其法律 ...

  2. MYSQL数据库的操作

    Mysql的连接方式: 1.原生函数:mysql_connect($server,$username,$password);   //打开一个到Mysql服务器的连接 mysql_select_db( ...

  3. 服务器发布tomcat的WEB项目供外网访问

    1.首先你要确定你有一个外网ip地址.如果你分配到的是一个局域网IP地址需要经过一系列的转换为外网ip地址,然后继续下面操作. 2.拿到外网IP地址,进行tomcat的server.xml文件的配置. ...

  4. hdu 1255

    覆盖的面积 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  5. Android Fragment 你应该知道的一切

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/42628537,本文出自:[张鸿洋的博客] 很久以前写过两篇Fragment的介绍 ...

  6. sublime自定义快键键不行,

    其实sublime自身就有格式化命令,就不再安装插件,位置在[Edit]->[Line]->[Reindent]但这个默认的命令没有快捷键,就重新定义了一下,想用习惯了的eclipse快捷 ...

  7. AngularJS中的身份验证

    欢迎大家指导与讨论 : )  一.  身份验证的意义  首先呢,网络应用的身份验证的意图在于:保护网站中的重要资源.基于某些原因这些资源并不能公开,比如付费资源(交过钱的用户才能上的网络课程),或者一 ...

  8. 添加Distributor失败

    上周做了一个case,客户无法为SQL Server instance配置remote distributor. 下面分享一下排查问题的过程,希望对您排查类似的问题所有帮助. 客户的环境中的SQL S ...

  9. SQL使用开窗函数与CTE查询每月销售额的前几名

    WITH tagTab AS( SELECT YearMonth, pm=RANK() OVER(PARTITION BY YearMonth ORDER BY amount DESC) FROM S ...

  10. C#:DataTable映射成Model

    这是数据库开发中经常遇到的问题,当然,这可以用现成的ORM框架来解决,但有些时候,如果DataSet/DataTable是第三方接口返回的,ORM就不方便了,还得自己处理. 反射自然必不可少的,另外考 ...