dispatchDraw():重写了父类的dispatchDraw();主要功能是判断抽屉是否打开、绘制指定的屏幕,可以绘制当前一屏,也可以绘制当前屏幕和下一屏幕,也可以绘制所有的屏幕,这儿的绘制指显示屏幕上的child(例如:app、folder、Wiget、shortcut)。和 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) { // 向左滑动,如果rightScreen为0
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);
}