/** * Track a motion scroll * * @param deltaY Amount to offset mMotionView. This is the accumulated delta since the motion * began. Positive numbers mean the user's finger is moving down the screen. * @param incrementalDeltaY Change in deltaY from the previous event. * @return true if we're already at the beginning/end of the list and have nothing to do. */ boolean trackMotionScroll(int deltaY, int incrementalDeltaY) { final int childCount = getChildCount(); if (childCount == 0) { return true; } final int firstTop = getChildAt(0).getLeft(); final int lastBottom = getChildAt(childCount - 1).getRight(); final Rect listPadding = mListPadding; // "effective padding" In this case is the amount of padding that affects // how much space should not be filled by items. If we don't clip to padding // there is no effective padding. int effectivePaddingTop = 0; int effectivePaddingBottom = 0; /*if ((mGroupFlags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK) { effectivePaddingTop = listPadding.left; effectivePaddingBottom = listPadding.right; }*/ // FIXME account for grid vertical spacing too? final int spaceAbove = effectivePaddingTop - firstTop; final int end = getWidth() - effectivePaddingBottom; final int spaceBelow = lastBottom - end; final int height = getWidth() - mPaddingRight - mPaddingLeft; if (deltaY < 0) { deltaY = Math.max(-(height - 1), deltaY); } else { deltaY = Math.min(height - 1, deltaY); } if (incrementalDeltaY < 0) { incrementalDeltaY = Math.max(-(height - 1), incrementalDeltaY); } else { incrementalDeltaY = Math.min(height - 1, incrementalDeltaY); } final int firstPosition = mFirstPosition; // Update our guesses for where the first and last views are if (firstPosition == 0) { mFirstPositionDistanceGuess = firstTop - listPadding.left; } else { mFirstPositionDistanceGuess += incrementalDeltaY; } if (firstPosition + childCount == mItemCount) { mLastPositionDistanceGuess = lastBottom + listPadding.right; } else { mLastPositionDistanceGuess += incrementalDeltaY; } final boolean cannotScrollDown = (firstPosition == 0 && firstTop >= listPadding.left && incrementalDeltaY >= 0); final boolean cannotScrollUp = (firstPosition + childCount == mItemCount && lastBottom <= getWidth() - listPadding.right && incrementalDeltaY <= 0); if (cannotScrollDown || cannotScrollUp) { return incrementalDeltaY != 0; } final boolean down = incrementalDeltaY < 0; final int headerViewsCount = 0; final int footerViewsStart = mItemCount; int start = 0; int count = 0; if (down) { int top = -incrementalDeltaY; // if ((mGroupFlags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK) { // top += listPadding.top; // } for (int i = 0; i < childCount; i++) { final View child = getChildAt(i); if (child.getAlpha() > ALPHA_RATIO_L0) { break; } else { count++; int position = firstPosition + i; if (position >= headerViewsCount && position < footerViewsStart) { // The view will be rebound to new data, clear any // system-managed transient state. mRecycler.addScrapView(child, position); Log.d(CARD_TAG, "addScrapView down -> position=" + position); } } } } else { // if ((mGroupFlags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK) { // bottom -= listPadding.bottom; // } int bottom = getWidth() - getPaddingRight() - incrementalDeltaY; for (int i = childCount - 1; i >= 0; i--) { final View child = getChildAt(i); if (child.getLeft() <= bottom) { break; } else { start = i; count++; int position = firstPosition + i; if (position >= headerViewsCount && position < footerViewsStart) { mRecycler.addScrapView(child, position); Log.d(CARD_TAG, "addScrapView up -> position=" + position); } } } } // mMotionViewNewTop = mMotionViewOriginalTop + deltaY; // mBlockLayoutRequests = true; if (count > 0) { Log.d(CARD_TAG, "addScrapView -> detachViewsFromParent start=" + start + ", count=" + count); detachViewsFromParent(start, count); mRecycler.removeSkippedScrap(); } final int scrollX = mScrollX; int paddingLeft = getPaddingLeft() + mChildrenContentMarginLeft; final int width = getWidth(); paddingLeft += mItemMarginLeft; // offsetChildrenTopAndBottom(incrementalDeltaY); offsetChildLeftAndRight(scrollX, paddingLeft); if (down) { mFirstPosition += count; } final int absIncrementalDeltaY = Math.abs(incrementalDeltaY); if (spaceAbove < absIncrementalDeltaY || spaceBelow < absIncrementalDeltaY) { fillGap(down); } mRecycler.fullyDetachScrapViews(); // mBlockLayoutRequests = false; // invokeOnItemScrollListener(); return false; } private void setupChild(View child, int position, int y, boolean flowDown, int childrenLeft, boolean selected, boolean isAttachedToWindow) { final boolean needToMeasure = !isAttachedToWindow || child.isLayoutRequested(); Log.d(CARD_TAG, "setupChild " + position); Log.d(CARD_TAG, "setupChild needToMeasure " + needToMeasure + ", isAttachedToWindow=" + isAttachedToWindow + ", isLayoutRequested= " + child.isLayoutRequested()); // Respect layout params that are already in the view. Otherwise make // some up... LayoutParams p = (LayoutParams) child.getLayoutParams(); if (p == null) { Log.d(CARD_TAG, "setupChild LayoutParams is null, generateDefaultLayoutParams"); p = (LayoutParams) generateDefaultLayoutParams(); } p.viewType = mAdapter.getItemViewType(position); p.isEnabled = mAdapter.isEnabled(position); if ((isAttachedToWindow && !p.forceAdd) /*|| (p.recycledHeaderFooter && p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)*/) { Log.d(CARD_TAG, "setupChild attachViewToParent"); attachViewToParent(child, flowDown ? -1 : 0, p); // If the view was previously attached for a different position, // then manually jump the drawables. if (isAttachedToWindow && (((LayoutParams) child.getLayoutParams()).scrappedFromPosition) != position) { child.jumpDrawablesToCurrentState(); } } else { p.forceAdd = false; // if (p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER) { // p.recycledHeaderFooter = true; // } Log.d(CARD_TAG, "setupChild addViewInLayout"); addViewInLayout(child, flowDown ? -1 : 0, p, true); // add view in layout will reset the RTL properties. We have to re-resolve them // child.resolveRtlPropertiesIfNeeded(); } if (needToMeasure) { final int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, mListPadding.left + mListPadding.right, p.width); final int lpHeight = p.height; final int childHeightSpec; if (lpHeight > 0) { childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY); } else { childHeightSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.UNSPECIFIED); } child.measure(childWidthSpec, childHeightSpec); } else { cleanupLayoutState(child); } // final int w = child.getMeasuredWidth(); // final int h = child.getMeasuredHeight(); final int childTop = getPaddingTop() + mItemMarginTop; int childLeft = getPaddingLeft() + mChildrenContentMarginLeft + mItemMarginLeft + position * (mItemMarginLeft + mCardViewWidth + mItemDividerWidth + mItemMarginRight); int childRight = childLeft + mCardViewWidth; final int childBottom = childTop + mCardViewHeight; // if (needToMeasure) { // final int childRight = childrenLeft + w; // final int childBottom = childTop + h; child.layout(childLeft, childTop, childRight, childBottom); // } else { // child.offsetLeftAndRight(childrenLeft - child.getLeft()); // child.offsetTopAndBottom(childTop - child.getTop()); // } // if (mCachingStarted && !child.isDrawingCacheEnabled()) { // child.setDrawingCacheEnabled(true); // } }
来源:51CTO
作者:书虫676
链接:https://blog.csdn.net/logan676/article/details/100586950