@Override
  protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    final int parentLeft = getPaddingLeft();
    final int parentRight = right - left - getPaddingRight();
    final int parentTop = getPaddingTop();
    final int parentBottom = bottom - top - getPaddingBottom();
    if (mScrollView != null && mScrollView.getVisibility() != GONE) {
      final FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mScrollView.getLayoutParams();

      final int width = mScrollView.getMeasuredWidth();
      final int height = mScrollView.getMeasuredHeight();

      int childLeft;
      int childTop;

      int gravity = lp.gravity;
      if (gravity == -1) {
        gravity = DEFAULT_CHILD_GRAVITY;
      }

      final int horizontalGravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
      final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;

      switch (horizontalGravity) {
        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;
      }

      mScrollView.layout(childLeft, childTop, childLeft + width, childTop + height);
    }

    if (mBackground != null) {
      final int scrollYCenterOffset = -mScrollView.getScrollY();
      final int offset = (int) (scrollYCenterOffset * mScrollDiff);
      // Log.d(TAG, "Layout Scroll Y: " + scrollYCenterOffset +
      // " ScrollDiff: " + mScrollDiff
      // + " Background Offset:" + offset);
      mBackground.layout(getLeft(), offset, mBackgroundRight, offset + mBackgroundBottom);
    }
  }