下面列出了android.support.v4.view.ViewCompat#getMinimumHeight ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Returns the amount of visible height in pixels used to define when to trigger a scrim
* visibility change.
*
*/
public int getScrimVisibleHeightTrigger() {
if (mScrimVisibleHeightTrigger >= 0) {
// If we have one explictly set, return it
return mScrimVisibleHeightTrigger;
}
// Otherwise we'll use the default computed value
final int insetTop = mLastInsets != null ? mLastInsets.getSystemWindowInsetTop() : 0;
final int minHeight = ViewCompat.getMinimumHeight(this);
if (minHeight > 0) {
// If we have a minHeight set, lets use 2 * minHeight (capped at our height)
return Math.min((minHeight * 2) + insetTop, getHeight());
}
// If we reach here then we don't have a min height set. Instead we'll take a
// guess at 1/3 of our height being visible
return getHeight() / 3;
}
private void snapToChildIfNeeded(CoordinatorLayout coordinatorLayout, AppBarLayout abl) {
final int offset = getTopBottomOffsetForScrollingSibling();
final View offsetChild = getChildOnOffset(abl, offset);
if (offsetChild != null) {
final LayoutParams lp = (LayoutParams) offsetChild.getLayoutParams();
if ((lp.getScrollFlags() & LayoutParams.FLAG_SNAP) == LayoutParams.FLAG_SNAP) {
// We're set the snap, so animate the offset to the nearest edge
int childTop = -offsetChild.getTop();
int childBottom = -offsetChild.getBottom();
// If the view is set only exit until it is collapsed, we'll abide by that
if ((lp.getScrollFlags() & LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED)
== LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED) {
childBottom += ViewCompat.getMinimumHeight(offsetChild);
}
final int newOffset = offset < (childBottom + childTop) / 2
? childBottom : childTop;
animateOffsetTo(coordinatorLayout, abl,
MathUtils.constrain(newOffset, -abl.getTotalScrollRange(), 0));
}
}
}
@Override
public Parcelable onSaveInstanceState(CoordinatorLayout parent, AppBarLayout appBarLayout) {
final Parcelable superState = super.onSaveInstanceState(parent, appBarLayout);
final int offset = getTopAndBottomOffset();
// Try and find the first visible child...
for (int i = 0, count = appBarLayout.getChildCount(); i < count; i++) {
View child = appBarLayout.getChildAt(i);
final int visBottom = child.getBottom() + offset;
if (child.getTop() + offset <= 0 && visBottom >= 0) {
final SavedState ss = new SavedState(superState);
ss.firstVisibleChildIndex = i;
ss.firstVisibileChildAtMinimumHeight =
visBottom == ViewCompat.getMinimumHeight(child);
ss.firstVisibileChildPercentageShown = visBottom / (float) child.getHeight();
return ss;
}
}
// Else we'll just return the super state
return superState;
}
private int getMinHeight(AppBarLayout layout, boolean forceQuickReturn) {
int minHeight = ViewCompat.getMinimumHeight(layout);
if (mScrollFlag.isFlagExitUntilCollapsedEnabled() || (minHeight > 0 && !mScrollFlag.isQuickReturnEnabled()) || forceQuickReturn) {
return minHeight > 0 ? minHeight : ViewCompat.getMinimumHeight(mScrollFlag.getView());
}
return 0;
}
@Override
public void onOffsetChanged(AppBarLayout layout, int verticalOffset) {
mCurrentOffset = verticalOffset;
final int insetTop = mLastInsets != null ? mLastInsets.getSystemWindowInsetTop() : 0;
final int scrollRange = layout.getTotalScrollRange();
for (int i = 0, z = getChildCount(); i < z; i++) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final ViewOffsetHelper offsetHelper = getViewOffsetHelper(child);
switch (lp.mCollapseMode) {
case LayoutParams.COLLAPSE_MODE_PIN:
if (getHeight() - insetTop + verticalOffset >= child.getHeight()) {
offsetHelper.setTopAndBottomOffset(-verticalOffset);
}
break;
case LayoutParams.COLLAPSE_MODE_PARALLAX:
offsetHelper.setTopAndBottomOffset(
Math.round(-verticalOffset * lp.mParallaxMult));
break;
}
}
// Update the collapsing text's fraction
final int expandRange = getHeight() - ViewCompat.getMinimumHeight(
StretchingLayout.this) - insetTop;
mCollapsingTextHelper.setExpansionFraction(
Math.abs(verticalOffset) / (float) expandRange);
if (Math.abs(verticalOffset) == scrollRange) {
// If we have some pinned children, and we're offset to only show those views,
// we want to be elevate
ViewCompat.setElevation(layout, layout.getTargetElevation());
} else {
// Otherwise, we're inline with the content
ViewCompat.setElevation(layout, 0f);
}
}
/**
* Returns the scroll range of all children.
*
* @return the scroll range in px
*/
public final int getTotalScrollRange() {
if (mTotalScrollRange != INVALID_SCROLL_RANGE) {
return mTotalScrollRange;
}
int range = 0;
int currentTop = getTop();
boolean allScroll = true;
for (int i = 0, z = getChildCount(); i < z; i++) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final int childBottom = getTop() + child.getBottom();
final int flags = lp.mScrollFlags;
if ((flags & LayoutParams.SCROLL_FLAG_SCROLL) != 0) {
// We're set to scroll so add the child's height
range += childBottom - currentTop;
currentTop = childBottom;
if ((flags & LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED) != 0) {
// For a collapsing scroll, we to take the collapsed height into account.
// We also break straight away since later views can't scroll beneath
// us
range -= ViewCompat.getMinimumHeight(child);
allScroll = false;
break;
}
} else {
allScroll = false;
// As soon as a view doesn't have the scroll flag, we end the range calculation.
// This is because views below can not scroll under a fixed view.
break;
}
}
if (allScroll) {
range += getBottom() - currentTop;
}
return mTotalScrollRange = Math.max(0, range - getTopInset());
}
final int getMinimumHeightForVisibleOverlappingContent() {
final int topInset = mLastInsets != null ? mLastInsets.getSystemWindowInsetTop() : 0;
final int minHeight = ViewCompat.getMinimumHeight(this);
if (minHeight != 0) {
// If this layout has a min height, use it (doubled)
return (minHeight * 2) + topInset;
}
// Otherwise, we'll use twice the min height of our last child
final int childCount = getChildCount();
return childCount >= 1
? (ViewCompat.getMinimumHeight(getChildAt(childCount - 1)) * 2) + topInset
: 0;
}
private int getMinHeight(AppBarLayout layout, boolean forceQuickReturn) {
int minHeight = ViewCompat.getMinimumHeight(layout);
if (mScrollFlag.isFlagExitUntilCollapsedEnabled() || (minHeight > 0 && !mScrollFlag.isQuickReturnEnabled()) || forceQuickReturn) {
return minHeight > 0 ? minHeight : ViewCompat.getMinimumHeight(mScrollFlag.getView());
}
return 0;
}
@Override
public void onOffsetChanged(AppBarLayout layout, int verticalOffset) {
mCurrentOffset = verticalOffset;
final int insetTop = mLastInsets != null ? mLastInsets.getSystemWindowInsetTop() : 0;
final int scrollRange = layout.getTotalScrollRange();
int height = 0;
for (int i = 0, z = getChildCount(); i < z; i++) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final ViewOffsetHelper offsetHelper = getViewOffsetHelper(child);
if (child instanceof Toolbar) {
height = child.getHeight();
}
switch (lp.mCollapseMode) {
case LayoutParams.COLLAPSE_MODE_PIN:
if (getHeight() - insetTop + verticalOffset >= child.getHeight()) {
offsetHelper.setTopAndBottomOffset(-verticalOffset);
}
break;
case LayoutParams.COLLAPSE_MODE_PARALLAX:
offsetHelper.setTopAndBottomOffset(
Math.round(-verticalOffset * lp.mParallaxMult));
break;
}
}
// Show or hide the scrims if needed
if (mContentScrim != null || mStatusBarScrim != null) {
if (mGooglePlayBehaviour) {
processLikeGooglePlayBehaviour(height, verticalOffset, scrollRange);
} else {
updateScrimVisibility();
}
}
if (mStatusBarScrim != null && insetTop > 0) {
ViewCompat.postInvalidateOnAnimation(GpCollapsingToolbar.this);
}
// Update the collapsing text's fraction
final int expandRange = getHeight() - ViewCompat.getMinimumHeight(GpCollapsingToolbar.this) - insetTop;
/*Log.e("LOG", "offset = " + verticalOffset + "; height = " + height + "; isTransparent = " + scrollRange
+ "; scrollRange = " + scrollRange);// + "; expandRange = " + expandRange);*/
mCollapsingTextHelper.setExpansionFraction(Math.abs(verticalOffset) / (float) expandRange);
}
private int getDownNestedPreScrollRange(boolean consumePreScroll) {
if (consumePreScroll != mShouldConsumePreScroll) {
mDownPreScrollRange = INVALID_SCROLL_RANGE;
mShouldConsumePreScroll = consumePreScroll;
}
if (mDownPreScrollRange != INVALID_SCROLL_RANGE) {
// If we already have a valid value, return it
return mDownPreScrollRange;
}
int range = 0;
int currentBottom = getBottom();
boolean allScroll = true;
for (int i = getChildCount() - 1; i >= 0; i--) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final int flags = lp.mScrollFlags;
if (consumePreScroll || (flags & LayoutParams.FLAG_QUICK_RETURN) == LayoutParams.FLAG_QUICK_RETURN) {
final int childTop = getTop() + child.getTop() - lp.topMargin;
// First take the margin into account
// The view has the quick return flag combination...
if ((flags & LayoutParams.SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED) != 0) {
// If they're set to enter collapsed, use the minimum height
int collapsedTop = getTop() + child.getBottom() - ViewCompat.getMinimumHeight(child);
range += currentBottom - collapsedTop;
} else {
// Else use the full height
range += currentBottom - childTop;
}
currentBottom = childTop;
} else if (range > 0) {
// If we've hit an non-quick return scrollable view, and we've already hit a
// quick return view, return now
allScroll = false;
break;
} else {
allScroll = false;
}
}
if (allScroll) {
range += currentBottom - getTop();
}
return mDownPreScrollRange = range;
}
/**
* Return the scroll range when scrolling down from a nested scroll.
*/
private int getDownNestedScrollRange() {
if (mDownScrollRange != INVALID_SCROLL_RANGE) {
// If we already have a valid value, return it
return mDownScrollRange;
}
int range = 0;
int currentTop = getTop();
boolean allScroll = true;
for (int i = 0, z = getChildCount(); i < z; i++) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final int childBottom = getTop() + child.getBottom();
final int flags = lp.mScrollFlags;
if ((flags & LayoutParams.SCROLL_FLAG_SCROLL) != 0) {
// We're set to scroll so add the child's height
range += childBottom - currentTop;
currentTop = childBottom;
if ((flags & LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED) != 0) {
// For a collapsing exit scroll, we to take the collapsed height into account.
// We also break the range straight away since later views can't scroll
// beneath us
range -= ViewCompat.getMinimumHeight(child) + getTopInset();
allScroll = false;
break;
}
} else {
// As soon as a view doesn't have the scroll flag, we end the range calculation.
// This is because views below can not scroll under a fixed view.
allScroll = false;
break;
}
}
if (allScroll) {
range += getBottom() - currentTop;
}
return mDownScrollRange = Math.max(0, range);
}
private int interpolateOffset(AppBarLayout layout, final int offset) {
final int absOffset = Math.abs(offset);
for (int i = 0, z = layout.getChildCount(); i < z; i++) {
final View child = layout.getChildAt(i);
final AppBarLayout.LayoutParams childLp = (LayoutParams) child.getLayoutParams();
final Interpolator interpolator = childLp.getScrollInterpolator();
if (absOffset >= child.getTop() && absOffset <= child.getBottom()) {
if (interpolator != null) {
int childScrollableHeight = 0;
final int flags = childLp.getScrollFlags();
if ((flags & LayoutParams.SCROLL_FLAG_SCROLL) != 0) {
// We're set to scroll so add the child's height plus margin
childScrollableHeight += child.getHeight() + childLp.topMargin
+ childLp.bottomMargin;
if ((flags & LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED) != 0) {
// For a collapsing scroll, we to take the collapsed height
// into account.
childScrollableHeight -= ViewCompat.getMinimumHeight(child);
}
}
if (ViewCompat.getFitsSystemWindows(child)) {
childScrollableHeight -= layout.getTopInset();
}
if (childScrollableHeight > 0) {
final int offsetForView = absOffset - child.getTop();
final int interpolatedDiff = Math.round(childScrollableHeight *
interpolator.getInterpolation(
offsetForView / (float) childScrollableHeight));
return Integer.signum(offset) * (child.getTop() + interpolatedDiff);
}
}
// If we get to here then the view on the offset isn't suitable for interpolated
// scrolling. So break out of the loop
break;
}
}
return offset;
}
/**
* The additional offset used to define when to trigger the scrim visibility change.
*/
final int getScrimTriggerOffset() {
return 2 * ViewCompat.getMinimumHeight(this);
}
@Override
public void onOffsetChanged(AppBarLayout layout, int verticalOffset) {
mCurrentOffset = verticalOffset;
final int insetTop = mLastInsets != null ? mLastInsets.getSystemWindowInsetTop() : 0;
final int scrollRange = layout.getTotalScrollRange();
for (int i = 0, z = getChildCount(); i < z; i++) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final ViewOffsetHelper offsetHelper = getViewOffsetHelper(child);
switch (lp.mCollapseMode) {
case LayoutParams.COLLAPSE_MODE_PIN:
if (getHeight() - insetTop + verticalOffset >= child.getHeight()) {
offsetHelper.setTopAndBottomOffset(-verticalOffset);
}
break;
case LayoutParams.COLLAPSE_MODE_PARALLAX:
offsetHelper.setTopAndBottomOffset(
Math.round(-verticalOffset * lp.mParallaxMult));
break;
}
}
// Show or hide the scrims if needed
if (mContentScrim != null || mStatusBarScrim != null) {
setScrimsShown(getHeight() + verticalOffset < getScrimTriggerOffset() + insetTop);
}
if (mStatusBarScrim != null && insetTop > 0) {
ViewCompat.postInvalidateOnAnimation(CollapsingToolbarLayout.this);
}
// Update the collapsing text's fraction
final int expandRange = getHeight() - ViewCompat.getMinimumHeight(
CollapsingToolbarLayout.this) - insetTop;
mCollapsingTextHelper.setExpansionFraction(
Math.abs(verticalOffset) / (float) expandRange);
if (Math.abs(verticalOffset) == scrollRange) {
// If we have some pinned children, and we're offset to only show those views,
// we want to be elevate
ViewCompat.setElevation(layout, layout.getTargetElevation());
} else {
// Otherwise, we're inline with the content
ViewCompat.setElevation(layout, 0f);
}
}
/**
* The additional offset used to define when to trigger the scrim visibility change.
*/
final int getScrimTriggerOffset() {
return 2 * ViewCompat.getMinimumHeight(this);
}
@Override
public void onOffsetChanged(AppBarLayout layout, int verticalOffset) {
mCurrentOffset = verticalOffset;
final int insetTop = mLastInsets != null ? mLastInsets.getSystemWindowInsetTop() : 0;
final int scrollRange = layout.getTotalScrollRange();
for (int i = 0, z = getChildCount(); i < z; i++) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final ViewOffsetHelper offsetHelper = getViewOffsetHelper(child);
switch (lp.mCollapseMode) {
case LayoutParams.COLLAPSE_MODE_PIN:
if (getHeight() - insetTop + verticalOffset >= child.getHeight()) {
offsetHelper.setTopAndBottomOffset(-verticalOffset);
}
break;
case LayoutParams.COLLAPSE_MODE_PARALLAX:
offsetHelper.setTopAndBottomOffset(
Math.round(-verticalOffset * lp.mParallaxMult));
break;
}
}
// Show or hide the scrims if needed
if (mContentScrim != null || mStatusBarScrim != null) {
setScrimsShown(getHeight() + verticalOffset < getScrimTriggerOffset() + insetTop);
}
if (mStatusBarScrim != null && insetTop > 0) {
ViewCompat.postInvalidateOnAnimation(FlexibleToolbarLayout.this);
}
// Update the collapsing text's fraction
final int expandRange = getHeight() - ViewCompat.getMinimumHeight(
FlexibleToolbarLayout.this) - insetTop;
float fraction = Math.abs(verticalOffset) / (float) expandRange;
mTitleCollapsingTextHelper.setExpansionFraction(fraction);
mSubtitleCollapsingTextHelper.setExpansionFraction(fraction);
mIconCollapsingHelper.setExpansionFraction(fraction);
}