Launcher实现左右循环滑动

 dispatchDraw()重写了父类的dispatchDraw();主要功能是判断抽屉是否打开、绘制指定的屏幕,可以绘制当前一屏,也可以绘制当前屏幕和下一屏幕,也可以绘制所有的屏幕,这儿的绘制指显示屏幕上的child(例如:appfolderWigetshortcut)。和 computeScroll()中的setCurrentScreen(mCurrentScreen)方法配合使用可以实现屏幕的拖动多少显示多少的功能。

实现循环滑动主要是考虑左右临界时屏幕绘制

protected void dispatchDraw(Canvas canvas) {

boolean restore = false;

int restoreCount = 0;

boolean fastDraw = mTouchState != TOUCH_STATE_SCROLLING && mNextScreen == INVALID_SCREEN;

  if (fastDraw) {

                drawChild(canvas, getChildAt(mCurrentScreen), getDrawingTime());

//在非滑动中、非临界条件的正常情况下绘制屏幕

            } else {

                long drawingTime = getDrawingTime();

                int width = getWidth();

                float scrollPos = (float) getScrollX() / width;

                boolean endlessScrolling = true;

 

                int leftScreen;

                int rightScreen;

                boolean isScrollToRight = false;

                int childCount = getChildCount();//其值为1、2、3----

                if (scrollPos < 0 && endlessScrolling) {

             //屏幕是向左滑到临界

                    leftScreen = childCount - 1;

                    rightScreen = 0;

                } else {//屏幕向右滑动到临界

                    leftScreen = Math.min( (int) scrollPos, childCount - 1 );

                    rightScreen = leftScreen + 1;

                    if (endlessScrolling) {

                        rightScreen = rightScreen % childCount;

                        isScrollToRight = true;

                    }

                }

   

              if (isScreenNoValid(leftScreen)) {

                    if (rightScreen == 0 && !isScrollToRight) { // 向左滑动,如果rightScreen0

                        int offset = childCount * width;

                        canvas.translate(-offset, 0);

                        drawChild(canvas, getChildAt(leftScreen), drawingTime);

                        canvas.translate(+offset, 0);

                    } else {

                        drawChild(canvas, getChildAt(leftScreen), drawingTime);

                    }

                }

                if (scrollPos != leftScreen && isScreenNoValid(rightScreen)) {//向右滑动

                    if (endlessScrolling && rightScreen == 0  && isScrollToRight) {

                         int offset = childCount * width;

                         canvas.translate(+offset, 0);

                         drawChild(canvas, getChildAt(rightScreen), drawingTime);

                         canvas.translate(-offset, 0);

                    } else {

                        drawChild(canvas, getChildAt(rightScreen), drawingTime);

                    }

                }

 

            }

 

 

}

private boolean isScreenNoValid(int screen) {    //判断非临界条件下所在的屏幕,如果是//临界则返回false

   return screen >= 0 && screen < getChildCount();

 

 }

 

private void snapToScreen(int whichScreen, int velocity, boolean settle) {

        //if (!mScroller.isFinished()) return;

       // whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));

 

       whichScreen = Math.max((true ? -1 : 0),Math.min(whichScreen, getChildCount() - (true ? 0 : 1)));

       mNextScreen = whichScreen;

       View focusedChild = getFocusedChild();

       clearVacantCache();

       enableChildrenCache(mCurrentScreen, whichScreen);

 

//       mPreviousIndicator.setLevel(mNextScreen);

//       mNextIndicator.setLevel(mNextScreen);

//此Launcher有7个界面即screen child,从0——6,-1、7为临界值,当向左滑动为-1时即到了临界 应该使之切换到最右的界面6,反之亦然。

        if(-1 == mNextScreen){

     mCurrentIndicator.setLevel(6);

 }else if(7 == mNextScreen){

            mCurrentIndicator.setLevel(0);

 }else{

            mCurrentIndicator.setLevel(mNextScreen);

   }

你可能感兴趣的:(Launcher实现左右循环滑动)