@Override public void computeScroll() { if (mScroller.computeScrollOffset()) { // This is called at drawing time by ViewGroup. We don't want to // re-show the scrollbars at this point, which scrollTo will do, // so we replicate most of scrollTo here. // // It's a little odd to call onScrollChanged from inside the drawing. // // It is, except when you remember that computeScroll() is used to // animate scrolling. So unless we want to defer the onScrollChanged() // until the end of the animated scrolling, we don't really have a // choice here. // // I agree. The alternative, which I think would be worse, is to post // something and tell the subclasses later. This is bad because there // will be a window where mScrollX/Y is different from what the app // thinks it is. // int oldX = getScrollX(); // mScrollX; int oldY = getScrollY(); // mScrollY; int x = mScroller.getCurrX(); int y = mScroller.getCurrY(); CFUtil.Log("sx=" + x + ", sy=" + y); if (oldX != x || oldY != y) { final int rangeY = getScrollRangeY(); // final int overscrollMode = getOverScrollMode(); // final boolean canOverscroll = overscrollMode == OVER_SCROLL_ALWAYS || // (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0); // overScrollBy(x - oldX, y - oldY, oldX, oldY, 0, range, // 0, mOverflingDistance, false); scrollTo(x, y); onScrollChanged(getScrollX(), getScrollY(), oldX, oldY); // if (canOverscroll) { // if (y < 0 && oldY >= 0) { // mEdgeGlowTop.onAbsorb((int) mScroller.getCurrVelocity()); // } else if (y > range && oldY <= range) { // mEdgeGlowBottom.onAbsorb((int) mScroller.getCurrVelocity()); // } // } } postInvalidate(); // if (!awakenScrollBars()) { // // Keep on drawing until the animation has finished. // postInvalidateOnAnimation(); // } } // else { // if (mFlingStrictSpan != null) { // mFlingStrictSpan.finish(); // mFlingStrictSpan = null; // } // } }
// @Override protected void layoutChildren() { // super.layoutChildren(); CFUtil.Log("layoutChildren"); final int count = mCellsCountX * mCellsCountY; removeAllViewsInLayout(); for (int i = 0; i < count; i++) { View child = mCells.get(i); if (child == null) continue; addViewInLayout(child, -1, child.getLayoutParams()); // if(!mCellsPos.containsKey(child)) continue; int index = mCellsPos.get(child); int x = toXFrom2(index); int y = toYFrom2(index); int xp = getCellsXInPixels(x); int yp = getCellsYInPixels(y); child.layout(xp, yp, xp + child.getMeasuredWidth(), yp + child.getMeasuredHeight()); } }
// @SuppressLint("NewApi") public void fling(int velocityX, int velocityY) { CFUtil.Log("fling " + velocityY + ", " + velocityY); if (getChildCount() > 0) { int height = getHeight() - getPaddingBottom() - getPaddingTop(); int width = getWidth() - getPaddingLeft() - getPaddingRight(); // int right = getChildAt(getChildCount()-1).getWidth(); // int bottom = getChildAt(getChildCount()-1).getHeight(); // mScroller.springBack(getScrollX(), getScrollY(), 0, width, 0, getScrollRange()); // mScroller.startScroll(getScrollX(), getScrollY(), velocityX, velocityY, 1000); mScroller.fling( getScrollX(), getScrollY(), velocityX, velocityY, // 0, Math.max(0, right - width), // 0, Math.max(0, bottom - height), 0, Math.max(0, getScrollRangeX()), 0, Math.max(0, getScrollRangeY()), width / 2, height / 2); // if (mFlingStrictSpan == null) { // mFlingStrictSpan = StrictMode.enterCriticalSpan("ScrollView-fling"); // } // postInvalidateOnAnimation(); postInvalidate(); } }
/** {@inheritDoc} */ @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); CFUtil.Log("onLayout"); layoutChildren(); // scrollTo(getScrollX(), getScrollY()); // final int parentLeft = getPaddingLeftWithForeground(); // final int parentRight = right - left - getPaddingRightWithForeground(); // // final int parentTop = getPaddingTopWithForeground(); // final int parentBottom = bottom - top - getPaddingBottomWithForeground(); // // mForegroundBoundsChanged = true; // // for (int i = 0; i < count; i++) { // final View child = getChildAt(i); // if (child.getVisibility() != GONE) { // final LayoutParams lp = (LayoutParams) child.getLayoutParams(); // // final int width = child.getMeasuredWidth(); // final int height = child.getMeasuredHeight(); // // int childLeft; // int childTop; // // int gravity = lp.gravity; // if (gravity == -1) { // gravity = DEFAULT_CHILD_GRAVITY; // } // // final int layoutDirection = getLayoutDirection(); // final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, // layoutDirection); // final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK; // // switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) { // case Gravity.LEFT: // childLeft = parentLeft + lp.leftMargin; // break; // case Gravity.CENTER_HORIZONTAL: // childLeft = parentLeft + (parentRight - parentLeft - width) / 2 + // lp.leftMargin - lp.rightMargin; // break; // case Gravity.RIGHT: // childLeft = parentRight - width - lp.rightMargin; // break; // default: // childLeft = parentLeft + lp.leftMargin; // } // // switch (verticalGravity) { // case Gravity.TOP: // childTop = parentTop + lp.topMargin; // break; // case Gravity.CENTER_VERTICAL: // childTop = parentTop + (parentBottom - parentTop - height) / 2 + // lp.topMargin - lp.bottomMargin; // break; // case Gravity.BOTTOM: // childTop = parentBottom - height - lp.bottomMargin; // break; // default: // childTop = parentTop + lp.topMargin; // } // // child.layout(childLeft, childTop, childLeft + width, childTop + height); // } // } }