zoukankan      html  css  js  c++  java
  • launcher 点击和滑动屏幕过程分析

    PagedView.java 是launcher的页面抽象类,桌面和all app界面都继承了该类

    launcher 的点击、滑动事件的处理主要有两个方法

    onInterceptTouchEvent(MotionEvent ev) 和 onTouchEvent(MotionEvent ev)

    这个两个方法的事件处理的调用分析 可以参考 这两篇文章

    http://www.blogjava.net/TiGERTiAN/archive/2011/02/22/344869.html

    http://blog.csdn.net/android_tutor/article/details/7193090

    根据打印的log分析,launcher中分别执行点击和滑动时这个两个方法调用关系

    1.在launcher的桌面和all app界面 执行点击事件的时候,

    若onInterceptTouchEvent方法 return false,则不会进入 onTouchEvent事件中,onInterceptTouchEvent会执行多次包括 ACTION_DOWN,ACTION_MOVE,ACTION_UP的事件;

    若onInterceptTouchEvent方法 return true,则会进入 onTouchEvent事件中,onInterceptTouchEvent只会执行一次ACTION_DOWN而onTouchEvent会执行多次包括上面的ACTION_DOWN,ACTION_MOVE,ACTION_UP的事件;

    2.在launcher的桌面和all app界面 执行滑动事件的时候

    若onInterceptTouchEvent方法 return false,则不会进入 onTouchEvent事件中,onInterceptTouchEvent会执行多次包括 ACTION_DOWN,ACTION_MOVE,ACTION_UP的事件;

    若onInterceptTouchEvent方法 return true,则会进入 onTouchEvent事件中,onInterceptTouchEvent只会执行一次本次ACTION_MOVE而onTouchEvent会执行多次包括上面的ACTION_DOWN,ACTION_MOVE,ACTION_UP的事件;

    ------------------------------------------------------滑动一次log-----------------------------

    01-01 13:22:34.680: I/lilei(8839): onInterceptTouchEvent___222__return:false action:0 mTouchState:0
    01-01 13:22:34.710: I/lilei(8839): _______onTouchEvent____
    01-01 13:22:34.710: I/lilei(8839): _______onTouchEvent____action:2
    01-01 13:22:34.710: I/lilei(8839): _______onTouchEvent___return_____
    01-01 13:22:34.710: I/lilei(8839): onInterceptTouchEvent___222__return:true action:2 mTouchState:1
    01-01 13:22:34.750: I/lilei(8839): _______onTouchEvent____
    01-01 13:22:34.750: I/lilei(8839): _______onTouchEvent____action:2
    01-01 13:22:34.750: I/lilei(8839): _______onTouchEvent___return_____
    01-01 13:22:34.780: I/lilei(8839): _______onTouchEvent____
    01-01 13:22:34.780: I/lilei(8839): _______onTouchEvent____action:2
    01-01 13:22:34.780: I/lilei(8839): _______onTouchEvent___return_____
    01-01 13:22:34.790: I/lilei(8839): _______onTouchEvent____
    01-01 13:22:34.790: I/lilei(8839): _______onTouchEvent____action:2
    01-01 13:22:34.790: I/lilei(8839): _______onTouchEvent___return_____
    01-01 13:22:34.800: I/lilei(8839): _______onTouchEvent____
    01-01 13:22:34.800: I/lilei(8839): _______onTouchEvent____action:1
    01-01 13:22:34.800: I/lilei(8839): _______onTouchEvent___return_____

    根据打印的log launcher 界面滑动一次看下代码代码调用流程

    1.首先调用onInterceptTouchEvent在的ACTION_DOWN事件 return false,

    MotionEvent.ACTION_DOWN做了那些操作呢?

    final int xDist = Math.abs(mScroller.getFinalX() - mScroller.getCurrX());
    final boolean finishedScrolling = (mScroller.isFinished() || xDist < mTouchSlop);
    if (finishedScrolling) {
          mTouchState = TOUCH_STATE_REST;
          mScroller.abortAnimation();
    } else {

         mTouchState = TOUCH_STATE_SCROLLING;
    }

    mScroller.getFinalX()是当前屏幕所在的位置(0,480,960..)和mScroller.getCurrX()当前滚动的位置

    若上个滚动结束,则设置mTouchState = TOUCH_STATE_REST并中断滚动动画,否则将状态设置为滚动状态mTouchState = TOUCH_STATE_SCROLLING

    2.由于上面的onInterceptTouchEvent 返回的是false

    下面会执行onInterceptTouchEvent的ACTION_MOVE事件 return true;

    MotionEvent.ACTION_MOVE做了那些操作

    if (mActivePointerId != INVALID_POINTER) {
                        //Fix Bug 191024, launcher optimize
                        float lastMotionX = mLastMotionX;
                        determineScrollingStart(ev);
                        if (mTouchState == TOUCH_STATE_SCROLLING)
                        {
                            mLastMotionX = lastMotionX;
                            onTouchEvent(ev);
                        }
                        //Fix Bug 191024, launcher optimize
                        break;
    }

    MotionEvent.ACTION_MOVE 调用了determineScrollingStart(ev)方法,

    该方法设置 状态mTouchState设置为TOUCH_STATE_SCROLLING,showScrollingIndicator显示页面指示条,取消当前页面长按事件等操作

    3.由于上面的onInterceptTouchEvent 返回的是true,

    下面会调用onTouchEvent的ACTION_MOVE事件,后面只会调用onTouchEvent的事件

    onTouchEvent的MotionEvent.ACTION_MOVE做了那些操作

    if (mTouchState == TOUCH_STATE_SCROLLING) {
                    // Scroll to follow the motion event
                    final int pointerIndex = ev.findPointerIndex(mActivePointerId);
                    final float x = ev.getX(pointerIndex);
                    final float deltaX = mLastMotionX + mLastMotionXRemainder - x;

                    mTotalMotionX += Math.abs(deltaX);

                    // Only scroll and update mLastMotionX if we have moved some discrete amount.  We
                    // keep the remainder because we are actually testing if we've moved from the last
                    // scrolled position (which is discrete).
                    if (Math.abs(deltaX) >= SCROLL_DISTANCE) {  //Fix Bug 191024, launcher optimize
                        mTouchX += deltaX;
                        mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
                        if (!mDeferScrollUpdate) {
                            Log.i("lilei", "scrollBy:"+(int) deltaX+" deltaX:"+deltaX);
                            scrollBy((int) deltaX, 0);
                            if (DEBUG) Log.d(TAG, "onTouchEvent().Scrolling: " + deltaX);
                        } else {
                            //invalidate(); //Fix Bug 191024, launcher optimize
                        }
                        mLastMotionX = x;
                        mLastMotionXRemainder = deltaX - (int) deltaX;
                    } else {
                        awakenScrollBars();
                    }

    } else {
              determineScrollingStart(ev);
    }

    若两次ACTION_MOVE之间移动距离deltaX大于最小移动单位,则调用scrollBy((int) deltaX, 0),让launcher界面移动手指移动距离

    4.当手指离开launcher界面时,会调用onTouchEvent的ACTION_UP事件

    if (mTouchState == TOUCH_STATE_SCROLLING) {
                    final int activePointerId = mActivePointerId;
                    final int pointerIndex = ev.findPointerIndex(activePointerId);
                    final float x = ev.getX(pointerIndex);
                    final VelocityTracker velocityTracker = mVelocityTracker;
                    velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
                    int velocityX = (int) velocityTracker.getXVelocity(activePointerId);
                    final int deltaX = (int) (x - mDownMotionX);
                    final int pageWidth = getScaledMeasuredWidth(getPageAt(mCurrentPage));
                    boolean isSignificantMove = Math.abs(deltaX) > pageWidth *
                            SIGNIFICANT_MOVE_THRESHOLD;

                    mTotalMotionX += Math.abs(mLastMotionX + mLastMotionXRemainder - x);

                    boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING &&
                            Math.abs(velocityX) > mFlingThresholdVelocity;

                    // In the case that the page is moved far to one direction and then is flung
                    // in the opposite direction, we use a threshold to determine whether we should
                    // just return to the starting page, or if we should skip one further.
                    boolean returnToOriginalPage = false;
                    if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD &&
                            Math.signum(velocityX) != Math.signum(deltaX) && isFling) {
                        returnToOriginalPage = true;
                    }

                    int finalPage;
                    // We give flings precedence over large moves, which is why we short-circuit our
                    // test for a large move if a fling has been registered. That is, a large
                    // move to the left and fling to the right will register as a fling to the right.
                    if (((isSignificantMove && deltaX > 0 && !isFling) ||
                            (isFling && velocityX > 0)) && mCurrentPage > (Launcher.CYCLE_SLIP ? -1 : 0)) {
                        finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
                        snapToPageWithVelocity(finalPage, velocityX);
                    } else if (((isSignificantMove && deltaX < 0 && !isFling) ||
                            (isFling && velocityX < 0)) &&
                            mCurrentPage < (Launcher.CYCLE_SLIP ? getChildCount() : getChildCount() - 1)) {
                        finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1;
                        snapToPageWithVelocity(finalPage, velocityX);
                    } else {
                        snapToDestination();
                    }
                } else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
                    // at this point we have not moved beyond the touch slop
                    // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
                    // we can just page
                    int nextPage = Math.max(0, mCurrentPage - 1);
                    if (nextPage != mCurrentPage) {
                        snapToPage(nextPage);
                    } else {
                        snapToDestination();
                    }

    } else if (mTouchState == TOUCH_STATE_NEXT_PAGE) {
                    // at this point we have not moved beyond the touch slop
                    // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
                    // we can just page
                    int nextPage = Math.min(getChildCount() - 1, mCurrentPage + 1);
                    if (nextPage != mCurrentPage) {
                        snapToPage(nextPage);
                    } else {
                        snapToDestination();
                    }
    } else {
                    onUnhandledTap(ev);
    }
    mTouchState = TOUCH_STATE_REST;

    mActivePointerId = INVALID_POINTER;
    releaseVelocityTracker();

    -------------------------------------------

    当手指离开launcher界面的时候是否切换屏幕的条件是 快速滑动isFling 或慢速滑动并且移动距离大于屏幕宽带的0.4倍(具体看代码参数变量的值)

    调用snapToPageWithVelocity()方法切换页面

    未完待续..

  • 相关阅读:
    sql server 2008安装要求
    当您尝试再次安装 SQL Server 时,SQL Server 2008年安装将会失败
    SQL Server数据库附加失败:错误5120和错误950
    sql server数据库数据查询成功
    MYSQL数据库连接
    解决java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver问题
    JSP数据库连接成功
    SQLServerException:通过端口 1433 连接到主机 localhost 的 TCP/IP 连接失败。
    win10中打开SQL Server配置管理器方法
    XHTML XML
  • 原文地址:https://www.cnblogs.com/adamli/p/3285131.html
Copyright © 2011-2022 走看看