private void adjustFirstCellsAndScroll() { int values[]; // values = adjustFirstCellsAndScroll(scrollX, firstColumn, widths); // scrollX = values[0]; // firstColumn = values[1]; // 切换应用导致重新布局时横向滚到最前端 scrollX = 0; firstColumn = 0; sumX = 0; values = adjustFirstCellsAndScroll(scrollY, firstRow, heights); scrollY = values[0]; firstRow = values[1]; if (lineView != null) { int maxY = lineView.getBottom() - height + lineView.getTop(); // data变化后maxY发生变化,而之前存的sumY也失效了,滑动时以现在的maxY为准 if (maxY < 0) { maxY = 0; } sumY = Math.min(maxY, sumY); lineView.scrollBy(0, sumY); } }
@Override public void scrollBy(int x, int y) { scrollX += x; scrollY += y; if (needRelayout) { return; } if (lineView != null) { int maxX = lineView.getRight() - width + lineView.getLeft(); int maxY = lineView.getBottom() - height + lineView.getTop(); int dX = x; int dY = y; sumX += x; sumY += y; if (maxY < 0) { maxY = 0; } if (sumX <= 0) { dX = x - sumX; sumX = 0; } else if (sumX >= maxX) { dX = maxX - sumX + x; sumX = maxX; } if (sumY <= 0) { dY = y - sumY; sumY = 0; } else if (sumY >= maxY) { dY = maxY - sumY + y; sumY = maxY; } lineView.scrollBy(dX, 0); lineView.scrollBy(0, dY); } scrollBounds(); /* * TODO Improve the algorithm. Think big diagonal movements. If we are * in the top left corner and scrollBy to the opposite corner. We will * have created the views from the top right corner on the X part and we * will have eliminated to generate the right at the Y. */ if (scrollX == 0) { // no op } else if (scrollX > 0) { while (widths[firstColumn + 1] < scrollX) { if (!rowViewList.isEmpty()) { removeLeft(); } scrollX -= widths[firstColumn + 1]; firstColumn++; } while (getFilledWidth() < width) { addRight(); } } else { while (!rowViewList.isEmpty() && getFilledWidth() - widths[firstColumn + rowViewList.size()] >= width) { removeRight(); } if (rowViewList.isEmpty()) { while (scrollX < 0) { firstColumn--; scrollX += widths[firstColumn + 1]; } while (getFilledWidth() < width) { addRight(); } } else { while (0 > scrollX) { addLeft(); firstColumn--; scrollX += widths[firstColumn + 1]; } } } if (scrollY == 0) { // no op } else if (scrollY > 0) { while (heights[firstRow + 1] < scrollY) { if (!columnViewList.isEmpty()) { removeTop(); } scrollY -= heights[firstRow + 1]; firstRow++; } while (getFilledHeight() < height) { addBottom(); } } else { while (!columnViewList.isEmpty() && getFilledHeight() - heights[firstRow + columnViewList.size()] >= height) { removeBottom(); } if (columnViewList.isEmpty()) { while (scrollY < 0) { firstRow--; scrollY += heights[firstRow + 1]; } while (getFilledHeight() < height) { addBottom(); } } else { while (0 > scrollY) { addTop(); firstRow--; scrollY += heights[firstRow + 1]; } } } repositionViews(); shadowsVisibility(); if (delegateTable != null && positiveScroll) { delegateTable.setPositiveScroll(false); delegateTable.scrollBy(x, 0); } }