@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (mScrollView != null) { measureChild( mScrollView, MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec), MeasureSpec.AT_MOST)); mScrollContentHeight = mScrollView.getChildAt(0).getMeasuredHeight(); mScrollViewHeight = mScrollView.getMeasuredHeight(); } if (mBackground != null) { int minHeight = 0; minHeight = (int) (mScrollViewHeight + mParallaxOffset * (mScrollContentHeight - mScrollViewHeight)); minHeight = Math.max(minHeight, MeasureSpec.getSize(heightMeasureSpec)); measureChild( mBackground, MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(minHeight, MeasureSpec.EXACTLY)); mBackgroundRight = getLeft() + mBackground.getMeasuredWidth(); mBackgroundBottom = getTop() + mBackground.getMeasuredHeight(); mScrollDiff = (float) (mBackground.getMeasuredHeight() - mScrollViewHeight) / (float) (mScrollContentHeight - mScrollViewHeight); } }
@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); } }