@Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int width = MeasureSpec.getSize(widthMeasureSpec);
    mBrightnessView.measure(exactly(width), MeasureSpec.UNSPECIFIED);
    final int brightnessHeight = mBrightnessView.getMeasuredHeight() + mBrightnessPaddingTop;
    mFooter.getView().measure(exactly(width), MeasureSpec.UNSPECIFIED);
    int r = -1;
    int c = -1;
    int rows = 0;
    for (TileRecord record : mRecords) {
      if (record.tileView.getVisibility() == GONE) continue;
      // wrap to next column if we've reached the max # of columns
      if (mUseMainTiles && r == 0 && c == 1) {
        r = 1;
        c = 0;
      } else if (r == -1 || c == (mColumns - 1)) {
        r++;
        c = 0;
      } else {
        c++;
      }
      record.row = r;
      record.col = c;
      rows = r + 1;
    }

    for (TileRecord record : mRecords) {
      if (record.tileView.getVisibility() == GONE) continue;
      final int cw = (mUseMainTiles && record.row == 0) ? mLargeCellWidth : mCellWidth;
      final int ch = (mUseMainTiles && record.row == 0) ? mLargeCellHeight : mCellHeight;
      record.tileView.measure(exactly(cw), exactly(ch));
    }
    int h = rows == 0 ? brightnessHeight : (getRowTop(rows) + mPanelPaddingBottom);
    if (mFooter.hasFooter()) {
      h += mFooter.getView().getMeasuredHeight();
    }

    mDetail.measure(exactly(width), MeasureSpec.UNSPECIFIED);
    if (isShowingDetail()) {
      Point size = new Point();
      getDisplay().getSize(size);
      final int panelBottom = (mContainerTop - mTranslationTop + h);
      final int detailMinHeight = size.y - mContainerTop - mPanelPaddingBottom;

      if (size.y > panelBottom) {
        int delta = size.y - panelBottom;
        // panel is smaller than screen size
        mDetail.measure(exactly(width), exactly(detailMinHeight - delta));
      } else {
        // panel is hanging below the screen
        mDetail.measure(exactly(width), exactly(detailMinHeight));
      }
    }
    mGridHeight = h;
    setMeasuredDimension(width, Math.max(h, mDetail.getMeasuredHeight()));
  }