mirror of
https://github.com/material-components/material-components-android.git
synced 2026-02-20 08:39:55 +08:00
am 5c3341f5: am 4c37ebd8: Merge "Window inset support for CoL + AppBarLayout" into mnc-dev
* commit '5c3341f5ab819b806ca8f63af6f9e27782e88401': Window inset support for CoL + AppBarLayout GitOrigin-RevId=72659081a3301eeadd659c7a063555260decdb90 PiperOrigin-RevId: 140548433
This commit is contained in:
parent
ea53e10e1d
commit
e8435b7bbd
@ -5,6 +5,7 @@ package android.support.design.widget {
|
||||
ctor public AppBarLayout(android.content.Context, android.util.AttributeSet);
|
||||
method public void addOnOffsetChangedListener(android.support.design.widget.AppBarLayout.OnOffsetChangedListener);
|
||||
method public float getTargetElevation();
|
||||
method public final int getTotalScrollRange();
|
||||
method public void removeOnOffsetChangedListener(android.support.design.widget.AppBarLayout.OnOffsetChangedListener);
|
||||
method public void setTargetElevation(float);
|
||||
}
|
||||
@ -56,13 +57,18 @@ package android.support.design.widget {
|
||||
ctor public CollapsingToolbarLayout(android.content.Context);
|
||||
ctor public CollapsingToolbarLayout(android.content.Context, android.util.AttributeSet);
|
||||
ctor public CollapsingToolbarLayout(android.content.Context, android.util.AttributeSet, int);
|
||||
method public int getForegroundScrimColor();
|
||||
method public android.graphics.drawable.Drawable getContentScrim();
|
||||
method public android.graphics.drawable.Drawable getStatusBarScrim();
|
||||
method public void setCollapsedTitleTextAppearance(int);
|
||||
method public void setCollapsedTitleTextColor(int);
|
||||
method public void setContentScrim(android.graphics.drawable.Drawable);
|
||||
method public void setContentScrimColor(int);
|
||||
method public void setContentScrimResource(int);
|
||||
method public void setExpandedTitleColor(int);
|
||||
method public void setExpandedTitleTextAppearance(int);
|
||||
method public void setForegroundScrimColor(int);
|
||||
method public void setForegroundScrimColorResource(int);
|
||||
method public void setStatusBarScrim(android.graphics.drawable.Drawable);
|
||||
method public void setStatusBarScrimColor(int);
|
||||
method public void setStatusBarScrimResource(int);
|
||||
method public void setTitle(java.lang.CharSequence);
|
||||
}
|
||||
|
||||
@ -89,12 +95,17 @@ package android.support.design.widget {
|
||||
method public void dispatchDependentViewsChanged(android.view.View);
|
||||
method public boolean doViewsOverlap(android.view.View, android.view.View);
|
||||
method public java.util.List<android.view.View> getDependencies(android.view.View);
|
||||
method public android.graphics.drawable.Drawable getStatusBarBackground();
|
||||
method public boolean isPointInChildBounds(android.view.View, int, int);
|
||||
method public void onAttachedToWindow();
|
||||
method public void onDetachedFromWindow();
|
||||
method public void onDraw(android.graphics.Canvas);
|
||||
method protected void onLayout(boolean, int, int, int, int);
|
||||
method public void onLayoutChild(android.view.View, int);
|
||||
method public void onMeasureChild(android.view.View, int, int, int, int);
|
||||
method public void setStatusBarBackground(android.graphics.drawable.Drawable);
|
||||
method public void setStatusBarBackgroundColor(int);
|
||||
method public void setStatusBarBackgroundResource(int);
|
||||
}
|
||||
|
||||
public static abstract class CoordinatorLayout.Behavior {
|
||||
@ -106,6 +117,7 @@ package android.support.design.widget {
|
||||
method public static java.lang.Object getTag(android.view.View);
|
||||
method public boolean isDirty(android.support.design.widget.CoordinatorLayout, V);
|
||||
method public boolean layoutDependsOn(android.support.design.widget.CoordinatorLayout, V, android.view.View);
|
||||
method public android.support.v4.view.WindowInsetsCompat onApplyWindowInsets(android.support.design.widget.CoordinatorLayout, V, android.support.v4.view.WindowInsetsCompat);
|
||||
method public boolean onDependentViewChanged(android.support.design.widget.CoordinatorLayout, V, android.view.View);
|
||||
method public boolean onInterceptTouchEvent(android.support.design.widget.CoordinatorLayout, V, android.view.MotionEvent);
|
||||
method public boolean onLayoutChild(android.support.design.widget.CoordinatorLayout, V, int);
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.support.design.widget;
|
||||
|
||||
import android.support.v4.view.OnApplyWindowInsetsListener;
|
||||
import android.view.View;
|
||||
|
||||
interface CoordinatorLayoutInsetsHelper {
|
||||
|
||||
void setupForWindowInsets(View view, OnApplyWindowInsetsListener insetsListener);
|
||||
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.support.design.widget;
|
||||
|
||||
import android.support.v4.view.OnApplyWindowInsetsListener;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.view.View;
|
||||
|
||||
class CoordinatorLayoutInsetsHelperLollipop implements CoordinatorLayoutInsetsHelper {
|
||||
|
||||
public void setupForWindowInsets(View view, OnApplyWindowInsetsListener insetsListener) {
|
||||
if (ViewCompat.getFitsSystemWindows(view)) {
|
||||
// First apply the insets listener
|
||||
ViewCompat.setOnApplyWindowInsetsListener(view, insetsListener);
|
||||
// Now set the sys ui flags to enable us to lay out in the window insets
|
||||
view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -19,6 +19,7 @@
|
||||
<public type="attr" name="backgroundTint"/>
|
||||
<public type="attr" name="backgroundTintMode"/>
|
||||
<public type="attr" name="collapsedTitleTextAppearance"/>
|
||||
<public type="attr" name="contentScrim"/>
|
||||
<public type="attr" name="elevation"/>
|
||||
<public type="attr" name="errorEnabled"/>
|
||||
<public type="attr" name="errorTextAppearance"/>
|
||||
@ -28,7 +29,6 @@
|
||||
<public type="attr" name="expandedTitleMarginStart"/>
|
||||
<public type="attr" name="expandedTitleTextAppearance"/>
|
||||
<public type="attr" name="fabSize"/>
|
||||
<public type="attr" name="foregroundScrimColor"/>
|
||||
<public type="attr" name="headerLayout"/>
|
||||
<public type="attr" name="hintTextAppearance"/>
|
||||
<public type="attr" name="itemBackground"/>
|
||||
@ -38,6 +38,8 @@
|
||||
<public type="attr" name="menu"/>
|
||||
<public type="attr" name="pressedTranslationZ"/>
|
||||
<public type="attr" name="rippleColor"/>
|
||||
<public type="attr" name="statusBarBackground"/>
|
||||
<public type="attr" name="statusBarScrim"/>
|
||||
<public type="attr" name="tabBackground"/>
|
||||
<public type="attr" name="tabContentStart"/>
|
||||
<public type="attr" name="tabGravity"/>
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
<public type="style" name="TextAppearance.Design.Tab"/>
|
||||
<public type="style" name="Widget.Design.AppBarLayout"/>
|
||||
<public type="style" name="Widget.Design.CollapsingToolbar"/>
|
||||
<public type="style" name="Widget.Design.CoordinatorLayout"/>
|
||||
<public type="style" name="Widget.Design.FloatingActionButton"/>
|
||||
<public type="style" name="Widget.Design.NavigationView"/>
|
||||
<public type="style" name="Widget.Design.Snackbar"/>
|
||||
|
||||
@ -94,6 +94,8 @@
|
||||
layout_keyline="index" where index is a 0-based index into
|
||||
this array. -->
|
||||
<attr name="keylines" format="reference"/>
|
||||
<!-- Drawable to display behind the status bar when the view is set to draw behind it. -->
|
||||
<attr name="statusBarBackground" format="reference"/>
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="CoordinatorLayout_LayoutParams">
|
||||
@ -207,9 +209,19 @@
|
||||
<attr name="expandedTitleMarginStart" format="dimension"/>
|
||||
<attr name="expandedTitleMarginBottom" format="dimension"/>
|
||||
<attr name="expandedTitleMarginEnd" format="dimension"/>
|
||||
<!-- The text appearance of the CollapsingToolbarLayouts title when it is fully
|
||||
'expanded' -->
|
||||
<attr name="expandedTitleTextAppearance" format="reference"/>
|
||||
<!-- The text appearance of the CollapsingToolbarLayouts title when it is fully
|
||||
'collapsed' -->
|
||||
<attr name="collapsedTitleTextAppearance" format="reference"/>
|
||||
<attr name="foregroundScrimColor" format="color"/>
|
||||
<!-- The drawable to use as a scrim on top of the CollapsingToolbarLayouts content when
|
||||
it has been scrolled sufficiently off screen. -->
|
||||
<attr name="contentScrim" format="color"/>
|
||||
<!-- The drawable to use as a scrim for the status bar content when the
|
||||
CollapsingToolbarLayout has been scrolled sufficiently off screen. Only works on
|
||||
Lollipop with the correct setup. -->
|
||||
<attr name="statusBarScrim" format="color" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="CollapsingAppBarLayout_LayoutParams">
|
||||
|
||||
@ -97,7 +97,7 @@
|
||||
<item name="expandedTitleMarginBottom">20dp</item>
|
||||
<item name="expandedTitleTextAppearance">@style/TextAppearance.AppCompat.Headline</item>
|
||||
<item name="collapsedTitleTextAppearance">@style/TextAppearance.AppCompat.Widget.ActionBar.Title</item>
|
||||
<item name="foregroundScrimColor">@android:color/transparent</item>
|
||||
<item name="statusBarScrim">?attr/colorPrimaryDark</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Design.AppBarLayout" parent="android:Widget">
|
||||
@ -105,5 +105,9 @@
|
||||
<item name="android:background">?attr/colorPrimary</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Design.CoordinatorLayout" parent="android:Widget">
|
||||
<item name="statusBarBackground">?attr/colorPrimaryDark</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@ import android.content.res.TypedArray;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.support.design.R;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.support.v4.view.WindowInsetsCompat;
|
||||
import android.support.v4.widget.ScrollerCompat;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
@ -118,6 +119,8 @@ public class AppBarLayout extends LinearLayout {
|
||||
|
||||
private float mTargetElevation;
|
||||
|
||||
private WindowInsetsCompat mLastInsets;
|
||||
|
||||
private final List<WeakReference<OnOffsetChangedListener>> mListeners;
|
||||
|
||||
public AppBarLayout(Context context) {
|
||||
@ -140,6 +143,16 @@ public class AppBarLayout extends LinearLayout {
|
||||
mListeners = new ArrayList<>();
|
||||
|
||||
ViewCompat.setElevation(this, mTargetElevation);
|
||||
|
||||
ViewCompat.setOnApplyWindowInsetsListener(this,
|
||||
new android.support.v4.view.OnApplyWindowInsetsListener() {
|
||||
@Override
|
||||
public WindowInsetsCompat onApplyWindowInsets(View v,
|
||||
WindowInsetsCompat insets) {
|
||||
setWindowInsets(insets);
|
||||
return insets.consumeSystemWindowInsets();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -238,11 +251,11 @@ public class AppBarLayout extends LinearLayout {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the scroll range of any children
|
||||
* Returns the scroll range of all children.
|
||||
*
|
||||
* @return the scroll range in px
|
||||
*/
|
||||
final int getTotalScrollRange() {
|
||||
public final int getTotalScrollRange() {
|
||||
if (mTotalScrollRange != INVALID_SCROLL_RANGE) {
|
||||
return mTotalScrollRange;
|
||||
}
|
||||
@ -262,9 +275,10 @@ public class AppBarLayout extends LinearLayout {
|
||||
|
||||
if ((flags & LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED) != 0) {
|
||||
// For a collapsing scroll, we to take the collapsed height into account.
|
||||
// We also return the range straight away since later views can't scroll beneath
|
||||
// We also break straight away since later views can't scroll beneath
|
||||
// us
|
||||
return range - ViewCompat.getMinimumHeight(child);
|
||||
range -= ViewCompat.getMinimumHeight(child);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// As soon as a view doesn't have the scroll flag, we end the range calculation.
|
||||
@ -272,7 +286,8 @@ public class AppBarLayout extends LinearLayout {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return mTotalScrollRange = range;
|
||||
final int top = mLastInsets != null ? mLastInsets.getSystemWindowInsetTop() : 0;
|
||||
return mTotalScrollRange = (range - top);
|
||||
}
|
||||
|
||||
final boolean hasScrollableChildren() {
|
||||
@ -361,16 +376,17 @@ public class AppBarLayout extends LinearLayout {
|
||||
}
|
||||
|
||||
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;
|
||||
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
|
||||
? (ViewCompat.getMinimumHeight(getChildAt(childCount - 1)) * 2) + topInset
|
||||
: 0;
|
||||
}
|
||||
|
||||
@ -398,6 +414,21 @@ public class AppBarLayout extends LinearLayout {
|
||||
return mTargetElevation;
|
||||
}
|
||||
|
||||
private void setWindowInsets(WindowInsetsCompat insets) {
|
||||
// Invalidate the total scroll range...
|
||||
mTotalScrollRange = INVALID_SCROLL_RANGE;
|
||||
mLastInsets = insets;
|
||||
|
||||
// Now dispatch them to our children
|
||||
for (int i = 0, z = getChildCount(); i < z; i++) {
|
||||
final View child = getChildAt(i);
|
||||
insets = ViewCompat.dispatchApplyWindowInsets(child, insets);
|
||||
if (insets.isConsumed()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class LayoutParams extends LinearLayout.LayoutParams {
|
||||
|
||||
/** @hide */
|
||||
@ -886,15 +917,15 @@ public class AppBarLayout extends LinearLayout {
|
||||
}
|
||||
|
||||
final AppBarLayout appBar = findFirstAppBarLayout(dependencies);
|
||||
if (appBar != null) {
|
||||
if (appBar.getMeasuredWidth() == 0 || appBar.getMeasuredHeight() == 0) {
|
||||
// If the AppBar hasn't been measured yet, we need to do it now
|
||||
parent.onMeasureChild(appBar, parentWidthMeasureSpec,
|
||||
widthUsed, parentHeightMeasureSpec, heightUsed);
|
||||
if (appBar != null && ViewCompat.isLaidOut(appBar)) {
|
||||
if (ViewCompat.getFitsSystemWindows(appBar)) {
|
||||
// If the AppBarLayout is fitting system windows then we need to also,
|
||||
// otherwise we'll get CoL's compatible layout functionality
|
||||
ViewCompat.setFitsSystemWindows(child, true);
|
||||
}
|
||||
|
||||
final int scrollRange = appBar.getTotalScrollRange();
|
||||
final int height = MeasureSpec.getSize(parentHeightMeasureSpec)
|
||||
final int height = parent.getHeight()
|
||||
- appBar.getMeasuredHeight() + scrollRange;
|
||||
final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(height,
|
||||
MeasureSpec.AT_MOST);
|
||||
|
||||
@ -19,21 +19,22 @@ package android.support.design.widget;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Rect;
|
||||
import android.support.annotation.ColorRes;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.DrawableRes;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.R;
|
||||
import android.support.v4.graphics.ColorUtils;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.support.v4.view.WindowInsetsCompat;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.Transformation;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
@ -52,7 +53,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||
*
|
||||
* <h3>Foreground scrim</h3>
|
||||
* A full-bleed scrim which is show or hidden when the scroll position has hit a certain threshold.
|
||||
* You can change the color via {@link #setForegroundScrimColor(int)}.
|
||||
* You can change this via {@link #setContentScrim(Drawable)}.
|
||||
*
|
||||
* <h3>Parallax scrolling children</h3>
|
||||
* Child views can opt to be scrolled within this layout in a parallax fashion.
|
||||
@ -66,11 +67,12 @@ import java.lang.annotation.RetentionPolicy;
|
||||
*
|
||||
* @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_collapsedTitleTextAppearance
|
||||
* @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_expandedTitleTextAppearance
|
||||
* @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_foregroundScrimColor
|
||||
* @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_contentScrim
|
||||
* @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_expandedTitleMargin
|
||||
* @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_expandedTitleMarginStart
|
||||
* @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_expandedTitleMarginEnd
|
||||
* @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_expandedTitleMarginBottom
|
||||
* @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_statusBarScrim
|
||||
*/
|
||||
public class CollapsingToolbarLayout extends FrameLayout {
|
||||
|
||||
@ -86,13 +88,18 @@ public class CollapsingToolbarLayout extends FrameLayout {
|
||||
private final Rect mRect = new Rect();
|
||||
private final CollapsingTextHelper mCollapsingTextHelper;
|
||||
|
||||
private int mForegroundScrimColor;
|
||||
private int mCurrentForegroundColor;
|
||||
private boolean mScrimIsShown;
|
||||
private Drawable mContentScrim;
|
||||
private Drawable mStatusBarScrim;
|
||||
private int mScrimAlpha;
|
||||
private boolean mScrimsAreShown;
|
||||
private ValueAnimatorCompat mScrimAnimator;
|
||||
|
||||
private AppBarLayout.OnOffsetChangedListener mOnOffsetChangedListener;
|
||||
|
||||
private int mCurrentOffset;
|
||||
|
||||
private WindowInsetsCompat mLastInsets;
|
||||
|
||||
public CollapsingToolbarLayout(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@ -150,12 +157,31 @@ public class CollapsingToolbarLayout extends FrameLayout {
|
||||
R.style.TextAppearance_AppCompat_Widget_ActionBar_Title);
|
||||
mCollapsingTextHelper.setCollapsedTextAppearance(tp);
|
||||
|
||||
mForegroundScrimColor = a.getColor(
|
||||
R.styleable.CollapsingToolbarLayout_foregroundScrimColor, 0);
|
||||
setContentScrim(a.getDrawable(R.styleable.CollapsingToolbarLayout_contentScrim));
|
||||
setStatusBarScrim(a.getDrawable(R.styleable.CollapsingToolbarLayout_statusBarScrim));
|
||||
|
||||
a.recycle();
|
||||
|
||||
setWillNotDraw(false);
|
||||
|
||||
ViewCompat.setOnApplyWindowInsetsListener(this,
|
||||
new android.support.v4.view.OnApplyWindowInsetsListener() {
|
||||
@Override
|
||||
public WindowInsetsCompat onApplyWindowInsets(View v,
|
||||
WindowInsetsCompat insets) {
|
||||
mLastInsets = insets;
|
||||
|
||||
for (int i = 0, z = getChildCount(); i < z; i++) {
|
||||
View child = getChildAt(i);
|
||||
LayoutParams lp = (LayoutParams) child.getLayoutParams();
|
||||
|
||||
if (lp.height != LayoutParams.MATCH_PARENT) {
|
||||
lp.topMargin = insets.getSystemWindowInsetTop();
|
||||
}
|
||||
}
|
||||
return insets.consumeSystemWindowInsets();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -200,12 +226,24 @@ public class CollapsingToolbarLayout extends FrameLayout {
|
||||
|
||||
// If we don't have a toolbar, the scrim will be not be drawn in drawChild() below.
|
||||
// Instead, we draw it here, before our collapsing text.
|
||||
if (mToolbar == null && Color.alpha(mCurrentForegroundColor) > 0) {
|
||||
canvas.drawColor(mCurrentForegroundColor);
|
||||
if (mToolbar == null && mContentScrim != null && mScrimAlpha > 0) {
|
||||
mContentScrim.mutate().setAlpha(mScrimAlpha);
|
||||
mContentScrim.draw(canvas);
|
||||
}
|
||||
|
||||
// Let the collapsing text helper draw it's text
|
||||
mCollapsingTextHelper.draw(canvas);
|
||||
|
||||
// Now draw the status bar scrim
|
||||
if (mStatusBarScrim != null && mScrimAlpha > 0) {
|
||||
final int topInset = mLastInsets != null ? mLastInsets.getSystemWindowInsetTop() : 0;
|
||||
if (topInset > 0) {
|
||||
mStatusBarScrim.setBounds(0, -mCurrentOffset, getWidth(),
|
||||
topInset - mCurrentOffset);
|
||||
mStatusBarScrim.mutate().setAlpha(mScrimAlpha);
|
||||
mStatusBarScrim.draw(canvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -213,14 +251,23 @@ public class CollapsingToolbarLayout extends FrameLayout {
|
||||
// This is a little weird. Our scrim needs to be behind the Toolbar (if it is present),
|
||||
// but in front of any other children which are behind it. To do this we intercept the
|
||||
// drawChild() call, and draw our scrim first when drawing the toolbar
|
||||
if (child == mToolbar && Color.alpha(mCurrentForegroundColor) > 0) {
|
||||
canvas.drawColor(mCurrentForegroundColor);
|
||||
if (child == mToolbar && mContentScrim != null && mScrimAlpha > 0) {
|
||||
mContentScrim.mutate().setAlpha(mScrimAlpha);
|
||||
mContentScrim.draw(canvas);
|
||||
}
|
||||
|
||||
// Carry on drawing the child...
|
||||
return super.drawChild(canvas, child, drawingTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
if (mContentScrim != null) {
|
||||
mContentScrim.setBounds(0, 0, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
@ -264,16 +311,16 @@ public class CollapsingToolbarLayout extends FrameLayout {
|
||||
}
|
||||
|
||||
private void showScrim() {
|
||||
if (!mScrimIsShown) {
|
||||
animateScrim(Color.alpha(mForegroundScrimColor));
|
||||
mScrimIsShown = true;
|
||||
if (!mScrimsAreShown) {
|
||||
animateScrim(255);
|
||||
mScrimsAreShown = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void hideScrim() {
|
||||
if (mScrimIsShown) {
|
||||
if (mScrimsAreShown) {
|
||||
animateScrim(0);
|
||||
mScrimIsShown = false;
|
||||
mScrimsAreShown = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -285,18 +332,14 @@ public class CollapsingToolbarLayout extends FrameLayout {
|
||||
mScrimAnimator.setUpdateListener(new ValueAnimatorCompat.AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimatorCompat animator) {
|
||||
final int newColor = ColorUtils.setAlphaComponent(
|
||||
mForegroundScrimColor, animator.getAnimatedIntValue());
|
||||
|
||||
if (newColor != mCurrentForegroundColor) {
|
||||
mCurrentForegroundColor = newColor;
|
||||
|
||||
// We need to manually invalidate ourselves and the Toolbar to ensure the scrim
|
||||
// is drawn
|
||||
invalidate();
|
||||
if (mToolbar != null) {
|
||||
mToolbar.invalidate();
|
||||
final int newAlpha = animator.getAnimatedIntValue();
|
||||
if (newAlpha != mScrimAlpha) {
|
||||
final Drawable contentScrim = mContentScrim;
|
||||
if (contentScrim != null && mToolbar != null) {
|
||||
ViewCompat.postInvalidateOnAnimation(mToolbar);
|
||||
}
|
||||
mScrimAlpha = newAlpha;
|
||||
ViewCompat.postInvalidateOnAnimation(CollapsingToolbarLayout.this);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -304,44 +347,126 @@ public class CollapsingToolbarLayout extends FrameLayout {
|
||||
mScrimAnimator.cancel();
|
||||
}
|
||||
|
||||
mScrimAnimator.setIntValues(Color.alpha(mCurrentForegroundColor), targetAlpha);
|
||||
mScrimAnimator.setIntValues(mScrimAlpha, targetAlpha);
|
||||
mScrimAnimator.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color to use for the foreground scrim. Providing a transparent color which disable
|
||||
* the scrim.
|
||||
* Set the drawable to use for the content scrim from resources. Providing null will disable
|
||||
* the scrim functionality.
|
||||
*
|
||||
* @param color ARGB color to use
|
||||
* @param drawable the drawable to display
|
||||
*
|
||||
* @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_foregroundScrimColor
|
||||
* @see #getForegroundScrimColor()
|
||||
* @attr ref R.styleable#CollapsingToolbarLayout_contentScrim
|
||||
* @see #getContentScrim()
|
||||
*/
|
||||
public void setForegroundScrimColor(int color) {
|
||||
mForegroundScrimColor = color;
|
||||
public void setContentScrim(@Nullable Drawable drawable) {
|
||||
if (mContentScrim != drawable) {
|
||||
if (mContentScrim != null) {
|
||||
mContentScrim.setCallback(null);
|
||||
}
|
||||
|
||||
mContentScrim = drawable;
|
||||
drawable.setBounds(0, 0, getWidth(), getHeight());
|
||||
drawable.setCallback(this);
|
||||
drawable.mutate().setAlpha(mScrimAlpha);
|
||||
ViewCompat.postInvalidateOnAnimation(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color to use for the foreground scrim from resources. Providing a transparent color
|
||||
* which disable the scrim.
|
||||
* Set the color to use for the content scrim.
|
||||
*
|
||||
* @param resId color resource id
|
||||
* @param color the color to display
|
||||
*
|
||||
* @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_foregroundScrimColor
|
||||
* @see #getForegroundScrimColor()
|
||||
* @attr ref R.styleable#CollapsingToolbarLayout_contentScrim
|
||||
* @see #getContentScrim()
|
||||
*/
|
||||
public void setForegroundScrimColorResource(@ColorRes int resId) {
|
||||
mForegroundScrimColor = getResources().getColor(resId);
|
||||
public void setContentScrimColor(int color) {
|
||||
setContentScrim(new ColorDrawable(color));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the color which is used for the foreground scrim.
|
||||
* Set the drawable to use for the content scrim from resources.
|
||||
*
|
||||
* @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_foregroundScrimColor
|
||||
* @see #setForegroundScrimColor(int)
|
||||
* @param resId drawable resource id
|
||||
*
|
||||
* @attr ref R.styleable#CollapsingToolbarLayout_contentScrim
|
||||
* @see #getContentScrim()
|
||||
*/
|
||||
public int getForegroundScrimColor() {
|
||||
return mForegroundScrimColor;
|
||||
public void setContentScrimResource(@DrawableRes int resId) {
|
||||
setContentScrim(ContextCompat.getDrawable(getContext(), resId));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the drawable which is used for the foreground scrim.
|
||||
*
|
||||
* @attr ref R.styleable#CollapsingToolbarLayout_contentScrim
|
||||
* @see #setContentScrim(Drawable)
|
||||
*/
|
||||
public Drawable getContentScrim() {
|
||||
return mContentScrim;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the drawable to use for the status bar scrim from resources.
|
||||
* Providing null will disable the scrim functionality.
|
||||
*
|
||||
* <p>This scrim is only shown when we have been given a top system inset.</p>
|
||||
*
|
||||
* @param drawable the drawable to display
|
||||
*
|
||||
* @attr ref R.styleable#CollapsingToolbarLayout_statusBarScrim
|
||||
* @see #getStatusBarScrim()
|
||||
*/
|
||||
public void setStatusBarScrim(@Nullable Drawable drawable) {
|
||||
if (mStatusBarScrim != drawable) {
|
||||
if (mStatusBarScrim != null) {
|
||||
mStatusBarScrim.setCallback(null);
|
||||
}
|
||||
|
||||
mStatusBarScrim = drawable;
|
||||
drawable.setCallback(this);
|
||||
drawable.mutate().setAlpha(mScrimAlpha);
|
||||
ViewCompat.postInvalidateOnAnimation(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color to use for the status bar scrim.
|
||||
*
|
||||
* <p>This scrim is only shown when we have been given a top system inset.</p>
|
||||
*
|
||||
* @param color the color to display
|
||||
*
|
||||
* @attr ref R.styleable#CollapsingToolbarLayout_statusBarScrim
|
||||
* @see #getStatusBarScrim()
|
||||
*/
|
||||
public void setStatusBarScrimColor(int color) {
|
||||
setStatusBarScrim(new ColorDrawable(color));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the drawable to use for the content scrim from resources.
|
||||
*
|
||||
* @param resId drawable resource id
|
||||
*
|
||||
* @attr ref R.styleable#CollapsingToolbarLayout_statusBarScrim
|
||||
* @see #getStatusBarScrim()
|
||||
*/
|
||||
public void setStatusBarScrimResource(@DrawableRes int resId) {
|
||||
setStatusBarScrim(ContextCompat.getDrawable(getContext(), resId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the drawable which is used for the status bar scrim.
|
||||
*
|
||||
* @attr ref R.styleable#CollapsingToolbarLayout_statusBarScrim
|
||||
* @see #setStatusBarScrim(Drawable)
|
||||
*/
|
||||
public Drawable getStatusBarScrim() {
|
||||
return mStatusBarScrim;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -382,6 +507,9 @@ public class CollapsingToolbarLayout extends FrameLayout {
|
||||
mCollapsingTextHelper.setExpandedTextColor(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* The additional offset used to define when to trigger the scrim visibility change.
|
||||
*/
|
||||
final int getScrimTriggerOffset() {
|
||||
return 2 * ViewCompat.getMinimumHeight(this);
|
||||
}
|
||||
@ -521,7 +649,10 @@ public class CollapsingToolbarLayout extends FrameLayout {
|
||||
private class OffsetUpdateListener implements AppBarLayout.OnOffsetChangedListener {
|
||||
@Override
|
||||
public void onOffsetChanged(AppBarLayout layout, int verticalOffset) {
|
||||
int pinnedHeight = 0;
|
||||
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);
|
||||
@ -530,10 +661,9 @@ public class CollapsingToolbarLayout extends FrameLayout {
|
||||
|
||||
switch (lp.mCollapseMode) {
|
||||
case LayoutParams.COLLAPSE_MODE_PIN:
|
||||
if (getHeight() + verticalOffset >= child.getHeight()) {
|
||||
if (getHeight() - insetTop + verticalOffset >= child.getHeight()) {
|
||||
offsetHelper.setTopAndBottomOffset(-verticalOffset);
|
||||
}
|
||||
pinnedHeight += child.getHeight();
|
||||
break;
|
||||
case LayoutParams.COLLAPSE_MODE_PARALLAX:
|
||||
offsetHelper.setTopAndBottomOffset(
|
||||
@ -542,22 +672,26 @@ public class CollapsingToolbarLayout extends FrameLayout {
|
||||
}
|
||||
}
|
||||
|
||||
// Show or hide the scrim if needed
|
||||
if (Color.alpha(mForegroundScrimColor) > 0) {
|
||||
if (getHeight() + verticalOffset < getScrimTriggerOffset()) {
|
||||
// Show or hide the scrims if needed
|
||||
if (mContentScrim != null || mStatusBarScrim != null) {
|
||||
if (getHeight() + verticalOffset < getScrimTriggerOffset() + insetTop) {
|
||||
showScrim();
|
||||
} else {
|
||||
hideScrim();
|
||||
}
|
||||
}
|
||||
|
||||
if (mStatusBarScrim != null && insetTop > 0) {
|
||||
ViewCompat.postInvalidateOnAnimation(CollapsingToolbarLayout.this);
|
||||
}
|
||||
|
||||
// Update the collapsing text's fraction
|
||||
final int expandRange = getHeight() - ViewCompat.getMinimumHeight(
|
||||
CollapsingToolbarLayout.this);
|
||||
CollapsingToolbarLayout.this) - insetTop;
|
||||
mCollapsingTextHelper.setExpansionFraction(
|
||||
Math.abs(verticalOffset) / (float) expandRange);
|
||||
|
||||
if (pinnedHeight > 0 && (getHeight() + verticalOffset) == pinnedHeight) {
|
||||
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());
|
||||
|
||||
@ -23,13 +23,17 @@ import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.SystemClock;
|
||||
import android.support.design.R;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.view.GravityCompat;
|
||||
import android.support.v4.view.NestedScrollingParent;
|
||||
import android.support.v4.view.NestedScrollingParentHelper;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.support.v4.view.WindowInsetsCompat;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
@ -82,8 +86,10 @@ public class CoordinatorLayout extends ViewGroup implements NestedScrollingParen
|
||||
static {
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
TOP_SORTED_CHILDREN_COMPARATOR = new ViewElevationComparator();
|
||||
INSETS_HELPER = new CoordinatorLayoutInsetsHelperLollipop();
|
||||
} else {
|
||||
TOP_SORTED_CHILDREN_COMPARATOR = null;
|
||||
INSETS_HELPER = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,6 +119,7 @@ public class CoordinatorLayout extends ViewGroup implements NestedScrollingParen
|
||||
};
|
||||
|
||||
static final Comparator<View> TOP_SORTED_CHILDREN_COMPARATOR;
|
||||
static final CoordinatorLayoutInsetsHelper INSETS_HELPER;
|
||||
|
||||
private final List<View> mDependencySortedChildren = new ArrayList<View>();
|
||||
private final List<View> mTempList1 = new ArrayList<>();
|
||||
@ -134,6 +141,10 @@ public class CoordinatorLayout extends ViewGroup implements NestedScrollingParen
|
||||
private OnPreDrawListener mOnPreDrawListener;
|
||||
private boolean mNeedsPreDrawListener;
|
||||
|
||||
private WindowInsetsCompat mLastInsets;
|
||||
private boolean mDrawStatusBarBackground;
|
||||
private Drawable mStatusBarBackground;
|
||||
|
||||
private final NestedScrollingParentHelper mNestedScrollingParentHelper =
|
||||
new NestedScrollingParentHelper(this);
|
||||
|
||||
@ -149,7 +160,7 @@ public class CoordinatorLayout extends ViewGroup implements NestedScrollingParen
|
||||
super(context, attrs, defStyleAttr);
|
||||
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CoordinatorLayout,
|
||||
defStyleAttr, 0);
|
||||
defStyleAttr, R.style.Widget_Design_CoordinatorLayout);
|
||||
final int keylineArrayRes = a.getResourceId(R.styleable.CoordinatorLayout_keylines, 0);
|
||||
if (keylineArrayRes != 0) {
|
||||
final Resources res = context.getResources();
|
||||
@ -160,7 +171,12 @@ public class CoordinatorLayout extends ViewGroup implements NestedScrollingParen
|
||||
mKeylines[i] *= density;
|
||||
}
|
||||
}
|
||||
mStatusBarBackground = a.getDrawable(R.styleable.CoordinatorLayout_statusBarBackground);
|
||||
a.recycle();
|
||||
|
||||
if (INSETS_HELPER != null) {
|
||||
INSETS_HELPER.setupForWindowInsets(this, new ApplyInsetsListener());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -191,6 +207,57 @@ public class CoordinatorLayout extends ViewGroup implements NestedScrollingParen
|
||||
mIsAttachedToWindow = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a drawable to draw in the insets area for the status bar.
|
||||
* Note that this will only be activated if this DrawerLayout fitsSystemWindows.
|
||||
*
|
||||
* @param bg Background drawable to draw behind the status bar
|
||||
*/
|
||||
public void setStatusBarBackground(Drawable bg) {
|
||||
mStatusBarBackground = bg;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the drawable used to draw in the insets area for the status bar.
|
||||
*
|
||||
* @return The status bar background drawable, or null if none set
|
||||
*/
|
||||
public Drawable getStatusBarBackground() {
|
||||
return mStatusBarBackground;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a drawable to draw in the insets area for the status bar.
|
||||
* Note that this will only be activated if this DrawerLayout fitsSystemWindows.
|
||||
*
|
||||
* @param resId Resource id of a background drawable to draw behind the status bar
|
||||
*/
|
||||
public void setStatusBarBackgroundResource(int resId) {
|
||||
setStatusBarBackground(resId != 0 ? ContextCompat.getDrawable(getContext(), resId) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a drawable to draw in the insets area for the status bar.
|
||||
* Note that this will only be activated if this DrawerLayout fitsSystemWindows.
|
||||
*
|
||||
* @param color Color to use as a background drawable to draw behind the status bar
|
||||
* in 0xAARRGGBB format.
|
||||
*/
|
||||
public void setStatusBarBackgroundColor(int color) {
|
||||
setStatusBarBackground(new ColorDrawable(color));
|
||||
}
|
||||
|
||||
private void setWindowInsets(WindowInsetsCompat insets) {
|
||||
if (mLastInsets != insets) {
|
||||
mLastInsets = insets;
|
||||
mDrawStatusBarBackground = insets != null && insets.getSystemWindowInsetTop() > 0;
|
||||
setWillNotDraw(!mDrawStatusBarBackground && getBackground() == null);
|
||||
dispatchChildApplyWindowInsets(insets);
|
||||
requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset all Behavior-related tracking records either to clean up or in preparation
|
||||
* for a new event stream. This should be called when attached or detached from a window,
|
||||
@ -518,6 +585,8 @@ public class CoordinatorLayout extends ViewGroup implements NestedScrollingParen
|
||||
final boolean isRtl = layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL;
|
||||
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
|
||||
final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
|
||||
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
||||
final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
|
||||
|
||||
final int widthPadding = paddingLeft + paddingRight;
|
||||
final int heightPadding = paddingTop + paddingBottom;
|
||||
@ -525,6 +594,8 @@ public class CoordinatorLayout extends ViewGroup implements NestedScrollingParen
|
||||
int heightUsed = getSuggestedMinimumHeight();
|
||||
int childState = 0;
|
||||
|
||||
final boolean applyInsets = mLastInsets != null && ViewCompat.getFitsSystemWindows(this);
|
||||
|
||||
final int childCount = mDependencySortedChildren.size();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
final View child = mDependencySortedChildren.get(i);
|
||||
@ -545,11 +616,27 @@ public class CoordinatorLayout extends ViewGroup implements NestedScrollingParen
|
||||
}
|
||||
}
|
||||
|
||||
int childWidthMeasureSpec = widthMeasureSpec;
|
||||
int childHeightMeasureSpec = heightMeasureSpec;
|
||||
if (applyInsets && !ViewCompat.getFitsSystemWindows(child)) {
|
||||
// We're set to handle insets but this child isn't, so we will measure the
|
||||
// child as if there are no insets
|
||||
final int horizInsets = mLastInsets.getSystemWindowInsetLeft()
|
||||
+ mLastInsets.getSystemWindowInsetRight();
|
||||
final int vertInsets = mLastInsets.getSystemWindowInsetTop()
|
||||
+ mLastInsets.getSystemWindowInsetBottom();
|
||||
|
||||
childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
|
||||
widthSize - horizInsets, widthMode);
|
||||
childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
|
||||
heightSize - vertInsets, heightMode);
|
||||
}
|
||||
|
||||
final Behavior b = lp.getBehavior();
|
||||
if (b == null || !b.onMeasureChild(this, child, widthMeasureSpec, keylineWidthUsed,
|
||||
heightMeasureSpec, 0)) {
|
||||
onMeasureChild(child, widthMeasureSpec, keylineWidthUsed,
|
||||
heightMeasureSpec, 0);
|
||||
if (b == null || !b.onMeasureChild(this, child, childWidthMeasureSpec, keylineWidthUsed,
|
||||
childHeightMeasureSpec, 0)) {
|
||||
onMeasureChild(child, childWidthMeasureSpec, keylineWidthUsed,
|
||||
childHeightMeasureSpec, 0);
|
||||
}
|
||||
|
||||
widthUsed = Math.max(widthUsed, widthPadding + child.getMeasuredWidth() +
|
||||
@ -568,6 +655,35 @@ public class CoordinatorLayout extends ViewGroup implements NestedScrollingParen
|
||||
setMeasuredDimension(width, height);
|
||||
}
|
||||
|
||||
private void dispatchChildApplyWindowInsets(WindowInsetsCompat insets) {
|
||||
if (insets.isConsumed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0, z = getChildCount(); i < z; i++) {
|
||||
final View child = getChildAt(i);
|
||||
if (ViewCompat.getFitsSystemWindows(child)) {
|
||||
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
|
||||
final Behavior b = lp.getBehavior();
|
||||
|
||||
if (b != null) {
|
||||
// If the view has a behavior, let it try first
|
||||
insets = b.onApplyWindowInsets(this, child, insets);
|
||||
if (insets.isConsumed()) {
|
||||
// If it consumed the insets, break
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Now let the view try and consume them
|
||||
insets = ViewCompat.dispatchApplyWindowInsets(child, insets);
|
||||
if (insets.isConsumed()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to lay out each individual child view unless a
|
||||
* {@link CoordinatorLayout.Behavior Behavior} is present. The Behavior may choose to
|
||||
@ -608,6 +724,18 @@ public class CoordinatorLayout extends ViewGroup implements NestedScrollingParen
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas c) {
|
||||
super.onDraw(c);
|
||||
if (mDrawStatusBarBackground && mStatusBarBackground != null) {
|
||||
final int inset = mLastInsets != null ? mLastInsets.getSystemWindowInsetTop() : 0;
|
||||
if (inset > 0) {
|
||||
mStatusBarBackground.setBounds(0, 0, getWidth(), inset);
|
||||
mStatusBarBackground.draw(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the last known child position rect for the given child view.
|
||||
* This will be used when checking if a child view's position has changed between frames.
|
||||
@ -851,6 +979,17 @@ public class CoordinatorLayout extends ViewGroup implements NestedScrollingParen
|
||||
getPaddingTop() + lp.topMargin,
|
||||
getWidth() - getPaddingRight() - lp.rightMargin,
|
||||
getHeight() - getPaddingBottom() - lp.bottomMargin);
|
||||
|
||||
if (mLastInsets != null && ViewCompat.getFitsSystemWindows(this)
|
||||
&& !ViewCompat.getFitsSystemWindows(child)) {
|
||||
// If we're set to handle insets but this child isn't, then it has been measured as
|
||||
// if there are no insets. We need to lay it out to match.
|
||||
parent.left += mLastInsets.getSystemWindowInsetLeft();
|
||||
parent.top += mLastInsets.getSystemWindowInsetTop();
|
||||
parent.right -= mLastInsets.getSystemWindowInsetRight();
|
||||
parent.bottom -= mLastInsets.getSystemWindowInsetBottom();
|
||||
}
|
||||
|
||||
final Rect out = mTempRect2;
|
||||
GravityCompat.apply(resolveGravity(lp.gravity), child.getMeasuredWidth(),
|
||||
child.getMeasuredHeight(), parent, out, layoutDirection);
|
||||
@ -1885,6 +2024,25 @@ public class CoordinatorLayout extends ViewGroup implements NestedScrollingParen
|
||||
float velocityX, float velocityY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the window insets have changed.
|
||||
*
|
||||
* <p>Any Behavior associated with the direct child of the CoordinatorLayout may elect
|
||||
* to handle the window inset change on behalf of it's associated view.
|
||||
* </p>
|
||||
*
|
||||
* @param coordinatorLayout the CoordinatorLayout parent of the view this Behavior is
|
||||
* associated with
|
||||
* @param child the child view of the CoordinatorLayout this Behavior is associated with
|
||||
* @param insets the new window insets.
|
||||
*
|
||||
* @return The insets supplied, minus any insets that were consumed
|
||||
*/
|
||||
public WindowInsetsCompat onApplyWindowInsets(CoordinatorLayout coordinatorLayout,
|
||||
V child, WindowInsetsCompat insets) {
|
||||
return insets;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2247,4 +2405,12 @@ public class CoordinatorLayout extends ViewGroup implements NestedScrollingParen
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
final class ApplyInsetsListener implements android.support.v4.view.OnApplyWindowInsetsListener {
|
||||
@Override
|
||||
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
|
||||
setWindowInsets(insets);
|
||||
return insets.consumeSystemWindowInsets();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user