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);
    }
  }