1a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes/* 2a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * Copyright (C) 2015 The Android Open Source Project 3a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * 4a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * Licensed under the Apache License, Version 2.0 (the "License"); 5a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * you may not use this file except in compliance with the License. 6a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * You may obtain a copy of the License at 7a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * 8a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * http://www.apache.org/licenses/LICENSE-2.0 9a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * 10a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * Unless required by applicable law or agreed to in writing, software 11a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * distributed under the License is distributed on an "AS IS" BASIS, 12a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * See the License for the specific language governing permissions and 14a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * limitations under the License. 15a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes */ 16a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 17a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banespackage android.support.design.widget; 18a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 19a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banesimport android.content.Context; 20a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banesimport android.content.res.TypedArray; 21a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banesimport android.graphics.Canvas; 22a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banesimport android.graphics.Rect; 23d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banesimport android.graphics.Typeface; 246ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banesimport android.graphics.drawable.ColorDrawable; 256ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banesimport android.graphics.drawable.Drawable; 261701feace5652372dd2fe1913f74169a12e2c940Chris Banesimport android.support.annotation.ColorInt; 276ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banesimport android.support.annotation.DrawableRes; 2850dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banesimport android.support.annotation.IntDef; 296df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banesimport android.support.annotation.IntRange; 30d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banesimport android.support.annotation.NonNull; 316ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banesimport android.support.annotation.Nullable; 321701feace5652372dd2fe1913f74169a12e2c940Chris Banesimport android.support.annotation.StyleRes; 33a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banesimport android.support.design.R; 346ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banesimport android.support.v4.content.ContextCompat; 35bcb330de0c625b371010bada2a51363fc37b52ccChris Banesimport android.support.v4.graphics.drawable.DrawableCompat; 365c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banesimport android.support.v4.view.GravityCompat; 37a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banesimport android.support.v4.view.ViewCompat; 386ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banesimport android.support.v4.view.WindowInsetsCompat; 39a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banesimport android.support.v7.widget.Toolbar; 4031075a61da61f1f0184ee909a70b1efcd7cee807Chris Banesimport android.text.TextUtils; 41a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banesimport android.util.AttributeSet; 42a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banesimport android.view.Gravity; 43a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banesimport android.view.View; 44a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banesimport android.view.ViewGroup; 45631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banesimport android.view.ViewParent; 46a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banesimport android.widget.FrameLayout; 47a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 4850dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banesimport java.lang.annotation.Retention; 4950dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banesimport java.lang.annotation.RetentionPolicy; 5050dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes 51a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes/** 52a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * CollapsingToolbarLayout is a wrapper for {@link Toolbar} which implements a collapsing app bar. 53a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * It is designed to be used as a direct child of a {@link AppBarLayout}. 54a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * CollapsingToolbarLayout contains the following features: 55a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * 564837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes * <h4>Collapsing title</h4> 57a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * A title which is larger when the layout is fully visible but collapses and becomes smaller as 58a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * the layout is scrolled off screen. You can set the title to display via 59a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * {@link #setTitle(CharSequence)}. The title appearance can be tweaked via the 60a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * {@code collapsedTextAppearance} and {@code expandedTextAppearance} attributes. 61a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * 624837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes * <h4>Content scrim</h4> 63a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * A full-bleed scrim which is show or hidden when the scroll position has hit a certain threshold. 646ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * You can change this via {@link #setContentScrim(Drawable)}. 65a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * 664837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes * <h4>Status bar scrim</h4> 6779208cc336926148978ccb49861f986fada745e0Chris Banes * A scrim which is show or hidden behind the status bar when the scroll position has hit a certain 6879208cc336926148978ccb49861f986fada745e0Chris Banes * threshold. You can change this via {@link #setStatusBarScrim(Drawable)}. This only works 6917ed3263761329f6aa6796941358c41001fff325Chris Banes * on {@link android.os.Build.VERSION_CODES#LOLLIPOP LOLLIPOP} devices when we set to fit system 7017ed3263761329f6aa6796941358c41001fff325Chris Banes * windows. 7179208cc336926148978ccb49861f986fada745e0Chris Banes * 724837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes * <h4>Parallax scrolling children</h4> 73a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * Child views can opt to be scrolled within this layout in a parallax fashion. 74a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * See {@link LayoutParams#COLLAPSE_MODE_PARALLAX} and 75a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * {@link LayoutParams#setParallaxMultiplier(float)}. 76a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * 774837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes * <h4>Pinned position children</h4> 78a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * Child views can opt to be pinned in space globally. This is useful when implementing a 79a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * collapsing as it allows the {@link Toolbar} to be fixed in place even though this layout is 80a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * moving. See {@link LayoutParams#COLLAPSE_MODE_PIN}. 81a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * 824837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes * <p><strong>Do not manually add views to the Toolbar at run time</strong>. 834837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes * We will add a 'dummy view' to the Toolbar which allows us to work out the available space 844837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes * for the title. This can interfere with any views which you add.</p> 854837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes * 86a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_collapsedTitleTextAppearance 87a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_expandedTitleTextAppearance 886ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_contentScrim 89a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_expandedTitleMargin 90a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_expandedTitleMarginStart 91a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_expandedTitleMarginEnd 92a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_expandedTitleMarginBottom 936ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_statusBarScrim 9479208cc336926148978ccb49861f986fada745e0Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_toolbarId 95a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes */ 96631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banespublic class CollapsingToolbarLayout extends FrameLayout { 97a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 986df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes private static final int DEFAULT_SCRIM_ANIMATION_DURATION = 600; 99a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 10079208cc336926148978ccb49861f986fada745e0Chris Banes private boolean mRefreshToolbar = true; 10179208cc336926148978ccb49861f986fada745e0Chris Banes private int mToolbarId; 102a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes private Toolbar mToolbar; 1034837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes private View mToolbarDirectChild; 104a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes private View mDummyView; 105a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 10634550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes private int mExpandedMarginStart; 10779208cc336926148978ccb49861f986fada745e0Chris Banes private int mExpandedMarginTop; 10834550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes private int mExpandedMarginEnd; 109a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes private int mExpandedMarginBottom; 110a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 11179208cc336926148978ccb49861f986fada745e0Chris Banes private final Rect mTmpRect = new Rect(); 112a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes private final CollapsingTextHelper mCollapsingTextHelper; 1131701feace5652372dd2fe1913f74169a12e2c940Chris Banes private boolean mCollapsingTitleEnabled; 114c06ea511ab9d97ed62ec10f10262f1c34b1905f0Chris Banes private boolean mDrawCollapsingTitle; 115a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 1166ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes private Drawable mContentScrim; 1176ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes private Drawable mStatusBarScrim; 1186ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes private int mScrimAlpha; 1196ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes private boolean mScrimsAreShown; 120f44e88b81821e61a65886cc7027617ca8995070bChris Banes private ValueAnimatorCompat mScrimAnimator; 121e852801f9258e00f89da48918b58a6e933643ab9Aurimas Liutikas private long mScrimAnimationDuration; 1226df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes private int mScrimVisibleHeightTrigger = -1; 123a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 124631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes private AppBarLayout.OnOffsetChangedListener mOnOffsetChangedListener; 125631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes 1266ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes private int mCurrentOffset; 1276ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes 1286ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes private WindowInsetsCompat mLastInsets; 1296ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes 130a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes public CollapsingToolbarLayout(Context context) { 131a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes this(context, null); 132a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 133a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 134a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes public CollapsingToolbarLayout(Context context, AttributeSet attrs) { 135b3ba94bf8b5cdae24e5a09a83813d72f2e2d8c1aChris Banes this(context, attrs, 0); 136a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 137a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 138a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes public CollapsingToolbarLayout(Context context, AttributeSet attrs, int defStyleAttr) { 139a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes super(context, attrs, defStyleAttr); 140a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 141809bb62055ad42b88f3a69308be222801b89fbd9Chris Banes ThemeUtils.checkAppCompatTheme(context); 142809bb62055ad42b88f3a69308be222801b89fbd9Chris Banes 143a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes mCollapsingTextHelper = new CollapsingTextHelper(this); 144a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes mCollapsingTextHelper.setTextSizeInterpolator(AnimationUtils.DECELERATE_INTERPOLATOR); 145a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 146a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes TypedArray a = context.obtainStyledAttributes(attrs, 147a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes R.styleable.CollapsingToolbarLayout, defStyleAttr, 148a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes R.style.Widget_Design_CollapsingToolbar); 149a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 1505c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes mCollapsingTextHelper.setExpandedTextGravity( 1515c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes a.getInt(R.styleable.CollapsingToolbarLayout_expandedTitleGravity, 1525c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes GravityCompat.START | Gravity.BOTTOM)); 1535c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes mCollapsingTextHelper.setCollapsedTextGravity( 1545c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes a.getInt(R.styleable.CollapsingToolbarLayout_collapsedTitleGravity, 1555c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes GravityCompat.START | Gravity.CENTER_VERTICAL)); 1565c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes 15734550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes mExpandedMarginStart = mExpandedMarginTop = mExpandedMarginEnd = mExpandedMarginBottom = 158a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes a.getDimensionPixelSize(R.styleable.CollapsingToolbarLayout_expandedTitleMargin, 0); 159a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 160a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes if (a.hasValue(R.styleable.CollapsingToolbarLayout_expandedTitleMarginStart)) { 16134550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes mExpandedMarginStart = a.getDimensionPixelSize( 162a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes R.styleable.CollapsingToolbarLayout_expandedTitleMarginStart, 0); 163a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 164a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes if (a.hasValue(R.styleable.CollapsingToolbarLayout_expandedTitleMarginEnd)) { 16534550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes mExpandedMarginEnd = a.getDimensionPixelSize( 166a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes R.styleable.CollapsingToolbarLayout_expandedTitleMarginEnd, 0); 167a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 16879208cc336926148978ccb49861f986fada745e0Chris Banes if (a.hasValue(R.styleable.CollapsingToolbarLayout_expandedTitleMarginTop)) { 16979208cc336926148978ccb49861f986fada745e0Chris Banes mExpandedMarginTop = a.getDimensionPixelSize( 17079208cc336926148978ccb49861f986fada745e0Chris Banes R.styleable.CollapsingToolbarLayout_expandedTitleMarginTop, 0); 17179208cc336926148978ccb49861f986fada745e0Chris Banes } 172a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes if (a.hasValue(R.styleable.CollapsingToolbarLayout_expandedTitleMarginBottom)) { 173a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes mExpandedMarginBottom = a.getDimensionPixelSize( 174a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes R.styleable.CollapsingToolbarLayout_expandedTitleMarginBottom, 0); 175a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 176a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 1771701feace5652372dd2fe1913f74169a12e2c940Chris Banes mCollapsingTitleEnabled = a.getBoolean( 1781701feace5652372dd2fe1913f74169a12e2c940Chris Banes R.styleable.CollapsingToolbarLayout_titleEnabled, true); 1791701feace5652372dd2fe1913f74169a12e2c940Chris Banes setTitle(a.getText(R.styleable.CollapsingToolbarLayout_title)); 1801701feace5652372dd2fe1913f74169a12e2c940Chris Banes 1819934230aa2959ee9f1802aa81fd21e25030b0d10Chris Banes // First load the default text appearances 1829934230aa2959ee9f1802aa81fd21e25030b0d10Chris Banes mCollapsingTextHelper.setExpandedTextAppearance( 1839934230aa2959ee9f1802aa81fd21e25030b0d10Chris Banes R.style.TextAppearance_Design_CollapsingToolbar_Expanded); 1849934230aa2959ee9f1802aa81fd21e25030b0d10Chris Banes mCollapsingTextHelper.setCollapsedTextAppearance( 1856759b1021d8198ad1d239bb30e5a102b99624bceAdam Lesinski android.support.v7.appcompat.R.style.TextAppearance_AppCompat_Widget_ActionBar_Title); 1869934230aa2959ee9f1802aa81fd21e25030b0d10Chris Banes 1879934230aa2959ee9f1802aa81fd21e25030b0d10Chris Banes // Now overlay any custom text appearances 1889934230aa2959ee9f1802aa81fd21e25030b0d10Chris Banes if (a.hasValue(R.styleable.CollapsingToolbarLayout_expandedTitleTextAppearance)) { 1899934230aa2959ee9f1802aa81fd21e25030b0d10Chris Banes mCollapsingTextHelper.setExpandedTextAppearance( 1909934230aa2959ee9f1802aa81fd21e25030b0d10Chris Banes a.getResourceId( 1919934230aa2959ee9f1802aa81fd21e25030b0d10Chris Banes R.styleable.CollapsingToolbarLayout_expandedTitleTextAppearance, 0)); 1929934230aa2959ee9f1802aa81fd21e25030b0d10Chris Banes } 1939934230aa2959ee9f1802aa81fd21e25030b0d10Chris Banes if (a.hasValue(R.styleable.CollapsingToolbarLayout_collapsedTitleTextAppearance)) { 1949934230aa2959ee9f1802aa81fd21e25030b0d10Chris Banes mCollapsingTextHelper.setCollapsedTextAppearance( 1959934230aa2959ee9f1802aa81fd21e25030b0d10Chris Banes a.getResourceId( 1969934230aa2959ee9f1802aa81fd21e25030b0d10Chris Banes R.styleable.CollapsingToolbarLayout_collapsedTitleTextAppearance, 0)); 1979934230aa2959ee9f1802aa81fd21e25030b0d10Chris Banes } 198a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 1996df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes mScrimVisibleHeightTrigger = a.getInt( 2006df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes R.styleable.CollapsingToolbarLayout_scrimVisibleHeightTrigger, -1); 2016df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes 2026df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes mScrimAnimationDuration = a.getInt( 2036df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes R.styleable.CollapsingToolbarLayout_scrimAnimationDuration, 2046df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes DEFAULT_SCRIM_ANIMATION_DURATION); 2056df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes 2066ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes setContentScrim(a.getDrawable(R.styleable.CollapsingToolbarLayout_contentScrim)); 2076ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes setStatusBarScrim(a.getDrawable(R.styleable.CollapsingToolbarLayout_statusBarScrim)); 208a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 20979208cc336926148978ccb49861f986fada745e0Chris Banes mToolbarId = a.getResourceId(R.styleable.CollapsingToolbarLayout_toolbarId, -1); 21079208cc336926148978ccb49861f986fada745e0Chris Banes 211a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes a.recycle(); 212a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 213a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes setWillNotDraw(false); 2146ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes 2156ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes ViewCompat.setOnApplyWindowInsetsListener(this, 2166ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes new android.support.v4.view.OnApplyWindowInsetsListener() { 2176ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes @Override 2186ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes public WindowInsetsCompat onApplyWindowInsets(View v, 2196ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes WindowInsetsCompat insets) { 22017ed3263761329f6aa6796941358c41001fff325Chris Banes return setWindowInsets(insets); 2216ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes } 2226ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes }); 223a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 224a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 225a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes @Override 226631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes protected void onAttachedToWindow() { 227631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes super.onAttachedToWindow(); 228631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes 229631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes // Add an OnOffsetChangedListener if possible 230631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes final ViewParent parent = getParent(); 231631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes if (parent instanceof AppBarLayout) { 232631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes if (mOnOffsetChangedListener == null) { 233631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes mOnOffsetChangedListener = new OffsetUpdateListener(); 234631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes } 235631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes ((AppBarLayout) parent).addOnOffsetChangedListener(mOnOffsetChangedListener); 236631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes } 23717ed3263761329f6aa6796941358c41001fff325Chris Banes 23817ed3263761329f6aa6796941358c41001fff325Chris Banes // We're attached, so lets request an inset dispatch 23917ed3263761329f6aa6796941358c41001fff325Chris Banes ViewCompat.requestApplyInsets(this); 240631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes } 241631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes 242631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes @Override 243631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes protected void onDetachedFromWindow() { 244631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes // Remove our OnOffsetChangedListener if possible and it exists 245631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes final ViewParent parent = getParent(); 246631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes if (mOnOffsetChangedListener != null && parent instanceof AppBarLayout) { 247631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes ((AppBarLayout) parent).removeOnOffsetChangedListener(mOnOffsetChangedListener); 248631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes } 249631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes 250631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes super.onDetachedFromWindow(); 251631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes } 252631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes 25317ed3263761329f6aa6796941358c41001fff325Chris Banes private WindowInsetsCompat setWindowInsets(WindowInsetsCompat insets) { 25417ed3263761329f6aa6796941358c41001fff325Chris Banes if (mLastInsets != insets) { 25517ed3263761329f6aa6796941358c41001fff325Chris Banes mLastInsets = insets; 25617ed3263761329f6aa6796941358c41001fff325Chris Banes requestLayout(); 25717ed3263761329f6aa6796941358c41001fff325Chris Banes } 25817ed3263761329f6aa6796941358c41001fff325Chris Banes return insets.consumeSystemWindowInsets(); 25917ed3263761329f6aa6796941358c41001fff325Chris Banes } 26017ed3263761329f6aa6796941358c41001fff325Chris Banes 261631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes @Override 262a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes public void draw(Canvas canvas) { 263a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes super.draw(canvas); 264a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 26550dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes // If we don't have a toolbar, the scrim will be not be drawn in drawChild() below. 26650dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes // Instead, we draw it here, before our collapsing text. 26779208cc336926148978ccb49861f986fada745e0Chris Banes ensureToolbar(); 2686ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes if (mToolbar == null && mContentScrim != null && mScrimAlpha > 0) { 2696ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes mContentScrim.mutate().setAlpha(mScrimAlpha); 2706ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes mContentScrim.draw(canvas); 27150dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes } 27250dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes 2734837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes // Let the collapsing text helper draw its text 274c06ea511ab9d97ed62ec10f10262f1c34b1905f0Chris Banes if (mCollapsingTitleEnabled && mDrawCollapsingTitle) { 2751701feace5652372dd2fe1913f74169a12e2c940Chris Banes mCollapsingTextHelper.draw(canvas); 2761701feace5652372dd2fe1913f74169a12e2c940Chris Banes } 2776ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes 2786ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes // Now draw the status bar scrim 2796ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes if (mStatusBarScrim != null && mScrimAlpha > 0) { 2806ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes final int topInset = mLastInsets != null ? mLastInsets.getSystemWindowInsetTop() : 0; 2816ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes if (topInset > 0) { 2826ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes mStatusBarScrim.setBounds(0, -mCurrentOffset, getWidth(), 2836ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes topInset - mCurrentOffset); 2846ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes mStatusBarScrim.mutate().setAlpha(mScrimAlpha); 2856ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes mStatusBarScrim.draw(canvas); 2866ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes } 2876ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes } 288a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 289a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 290a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes @Override 291a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes protected boolean drawChild(Canvas canvas, View child, long drawingTime) { 292a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes // This is a little weird. Our scrim needs to be behind the Toolbar (if it is present), 293a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes // but in front of any other children which are behind it. To do this we intercept the 294a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes // drawChild() call, and draw our scrim first when drawing the toolbar 29579208cc336926148978ccb49861f986fada745e0Chris Banes ensureToolbar(); 2966ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes if (child == mToolbar && mContentScrim != null && mScrimAlpha > 0) { 2976ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes mContentScrim.mutate().setAlpha(mScrimAlpha); 2986ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes mContentScrim.draw(canvas); 299a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 30050dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes 301a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes // Carry on drawing the child... 302a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes return super.drawChild(canvas, child, drawingTime); 303a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 304a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 305a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes @Override 3066ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes protected void onSizeChanged(int w, int h, int oldw, int oldh) { 3076ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes super.onSizeChanged(w, h, oldw, oldh); 3086ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes if (mContentScrim != null) { 3096ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes mContentScrim.setBounds(0, 0, w, h); 3106ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes } 3116ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes } 3126ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes 31379208cc336926148978ccb49861f986fada745e0Chris Banes private void ensureToolbar() { 31479208cc336926148978ccb49861f986fada745e0Chris Banes if (!mRefreshToolbar) { 31579208cc336926148978ccb49861f986fada745e0Chris Banes return; 31679208cc336926148978ccb49861f986fada745e0Chris Banes } 31779208cc336926148978ccb49861f986fada745e0Chris Banes 3184837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes // First clear out the current Toolbar 3194837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes mToolbar = null; 3204837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes mToolbarDirectChild = null; 32179208cc336926148978ccb49861f986fada745e0Chris Banes 3224837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes if (mToolbarId != -1) { 3234837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes // If we have an ID set, try and find it and it's direct parent to us 3244837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes mToolbar = (Toolbar) findViewById(mToolbarId); 3254837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes if (mToolbar != null) { 3264837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes mToolbarDirectChild = findDirectChild(mToolbar); 32779208cc336926148978ccb49861f986fada745e0Chris Banes } 32879208cc336926148978ccb49861f986fada745e0Chris Banes } 32979208cc336926148978ccb49861f986fada745e0Chris Banes 3304837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes if (mToolbar == null) { 3314837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes // If we don't have an ID, or couldn't find a Toolbar with the correct ID, try and find 3324837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes // one from our direct children 3334837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes Toolbar toolbar = null; 3344837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes for (int i = 0, count = getChildCount(); i < count; i++) { 3354837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes final View child = getChildAt(i); 3364837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes if (child instanceof Toolbar) { 3374837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes toolbar = (Toolbar) child; 3384837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes break; 3394837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes } 3404837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes } 3414837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes mToolbar = toolbar; 34279208cc336926148978ccb49861f986fada745e0Chris Banes } 34379208cc336926148978ccb49861f986fada745e0Chris Banes 3441701feace5652372dd2fe1913f74169a12e2c940Chris Banes updateDummyView(); 34579208cc336926148978ccb49861f986fada745e0Chris Banes mRefreshToolbar = false; 34679208cc336926148978ccb49861f986fada745e0Chris Banes } 34779208cc336926148978ccb49861f986fada745e0Chris Banes 3484837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes /** 3494837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes * Returns the direct child of this layout, which itself is the ancestor of the 3504837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes * given view. 3514837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes */ 3524837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes private View findDirectChild(final View descendant) { 3534837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes View directChild = descendant; 3544837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes for (ViewParent p = descendant.getParent(); p != this && p != null; p = p.getParent()) { 3554837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes if (p instanceof View) { 3564837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes directChild = (View) p; 3574837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes } 3584837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes } 3594837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes return directChild; 3604837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes } 3614837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes 3621701feace5652372dd2fe1913f74169a12e2c940Chris Banes private void updateDummyView() { 3631701feace5652372dd2fe1913f74169a12e2c940Chris Banes if (!mCollapsingTitleEnabled && mDummyView != null) { 3641701feace5652372dd2fe1913f74169a12e2c940Chris Banes // If we have a dummy view and we have our title disabled, remove it from its parent 3651701feace5652372dd2fe1913f74169a12e2c940Chris Banes final ViewParent parent = mDummyView.getParent(); 3661701feace5652372dd2fe1913f74169a12e2c940Chris Banes if (parent instanceof ViewGroup) { 3671701feace5652372dd2fe1913f74169a12e2c940Chris Banes ((ViewGroup) parent).removeView(mDummyView); 3681701feace5652372dd2fe1913f74169a12e2c940Chris Banes } 3691701feace5652372dd2fe1913f74169a12e2c940Chris Banes } 3701701feace5652372dd2fe1913f74169a12e2c940Chris Banes if (mCollapsingTitleEnabled && mToolbar != null) { 3711701feace5652372dd2fe1913f74169a12e2c940Chris Banes if (mDummyView == null) { 3721701feace5652372dd2fe1913f74169a12e2c940Chris Banes mDummyView = new View(getContext()); 3731701feace5652372dd2fe1913f74169a12e2c940Chris Banes } 3741701feace5652372dd2fe1913f74169a12e2c940Chris Banes if (mDummyView.getParent() == null) { 3751701feace5652372dd2fe1913f74169a12e2c940Chris Banes mToolbar.addView(mDummyView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 3761701feace5652372dd2fe1913f74169a12e2c940Chris Banes } 3771701feace5652372dd2fe1913f74169a12e2c940Chris Banes } 3781701feace5652372dd2fe1913f74169a12e2c940Chris Banes } 3791701feace5652372dd2fe1913f74169a12e2c940Chris Banes 3806ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes @Override 381fdd6ec4abeb9100944ea5c043ebc07a707cb4764Jens Ole Lauridsen protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 382fdd6ec4abeb9100944ea5c043ebc07a707cb4764Jens Ole Lauridsen ensureToolbar(); 383fdd6ec4abeb9100944ea5c043ebc07a707cb4764Jens Ole Lauridsen super.onMeasure(widthMeasureSpec, heightMeasureSpec); 384fdd6ec4abeb9100944ea5c043ebc07a707cb4764Jens Ole Lauridsen } 385fdd6ec4abeb9100944ea5c043ebc07a707cb4764Jens Ole Lauridsen 386fdd6ec4abeb9100944ea5c043ebc07a707cb4764Jens Ole Lauridsen @Override 387a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 388a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes super.onLayout(changed, left, top, right, bottom); 389a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 39079aa418487cdefb85d3c1fac32d6403a1ac6057dChris Banes // Update the collapsed bounds by getting it's transformed bounds. This needs to be done 39179aa418487cdefb85d3c1fac32d6403a1ac6057dChris Banes // before the children are offset below 39279aa418487cdefb85d3c1fac32d6403a1ac6057dChris Banes if (mCollapsingTitleEnabled && mDummyView != null) { 393c06ea511ab9d97ed62ec10f10262f1c34b1905f0Chris Banes // We only draw the title if the dummy view is being displayed (Toolbar removes 394c06ea511ab9d97ed62ec10f10262f1c34b1905f0Chris Banes // views if there is no space) 3956b0726e90aa7c4657f5bf7459fadbaf58905c3c8Chris Banes mDrawCollapsingTitle = ViewCompat.isAttachedToWindow(mDummyView) 3966b0726e90aa7c4657f5bf7459fadbaf58905c3c8Chris Banes && mDummyView.getVisibility() == VISIBLE; 397c06ea511ab9d97ed62ec10f10262f1c34b1905f0Chris Banes 398c06ea511ab9d97ed62ec10f10262f1c34b1905f0Chris Banes if (mDrawCollapsingTitle) { 399b1d11409409e0d166360397adfd1e765bef49591Chris Banes final boolean isRtl = ViewCompat.getLayoutDirection(this) 400b1d11409409e0d166360397adfd1e765bef49591Chris Banes == ViewCompat.LAYOUT_DIRECTION_RTL; 401b1d11409409e0d166360397adfd1e765bef49591Chris Banes 402b1d11409409e0d166360397adfd1e765bef49591Chris Banes // Update the collapsed bounds 4034837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes int bottomOffset = 0; 4044837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes if (mToolbarDirectChild != null && mToolbarDirectChild != this) { 4054837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes final LayoutParams lp = (LayoutParams) mToolbarDirectChild.getLayoutParams(); 4064837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes bottomOffset = lp.bottomMargin; 4074837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes } 408c06ea511ab9d97ed62ec10f10262f1c34b1905f0Chris Banes ViewGroupUtils.getDescendantRect(this, mDummyView, mTmpRect); 409b1d11409409e0d166360397adfd1e765bef49591Chris Banes mCollapsingTextHelper.setCollapsedBounds( 410b1d11409409e0d166360397adfd1e765bef49591Chris Banes mTmpRect.left + (isRtl 411b1d11409409e0d166360397adfd1e765bef49591Chris Banes ? mToolbar.getTitleMarginEnd() 412b1d11409409e0d166360397adfd1e765bef49591Chris Banes : mToolbar.getTitleMarginStart()), 413874a5968599b8c53212ff49af5c047b1211b547aChris Banes bottom + mToolbar.getTitleMarginTop() - mTmpRect.height() - bottomOffset, 414b1d11409409e0d166360397adfd1e765bef49591Chris Banes mTmpRect.right + (isRtl 415b1d11409409e0d166360397adfd1e765bef49591Chris Banes ? mToolbar.getTitleMarginStart() 416b1d11409409e0d166360397adfd1e765bef49591Chris Banes : mToolbar.getTitleMarginEnd()), 417874a5968599b8c53212ff49af5c047b1211b547aChris Banes bottom - bottomOffset - mToolbar.getTitleMarginBottom()); 41834550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes 419c06ea511ab9d97ed62ec10f10262f1c34b1905f0Chris Banes // Update the expanded bounds 420c06ea511ab9d97ed62ec10f10262f1c34b1905f0Chris Banes mCollapsingTextHelper.setExpandedBounds( 42134550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes isRtl ? mExpandedMarginEnd : mExpandedMarginStart, 422c06ea511ab9d97ed62ec10f10262f1c34b1905f0Chris Banes mTmpRect.bottom + mExpandedMarginTop, 42334550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes right - left - (isRtl ? mExpandedMarginStart : mExpandedMarginEnd), 424c06ea511ab9d97ed62ec10f10262f1c34b1905f0Chris Banes bottom - top - mExpandedMarginBottom); 425c06ea511ab9d97ed62ec10f10262f1c34b1905f0Chris Banes // Now recalculate using the new bounds 426c06ea511ab9d97ed62ec10f10262f1c34b1905f0Chris Banes mCollapsingTextHelper.recalculate(); 427c06ea511ab9d97ed62ec10f10262f1c34b1905f0Chris Banes } 42879aa418487cdefb85d3c1fac32d6403a1ac6057dChris Banes } 42979aa418487cdefb85d3c1fac32d6403a1ac6057dChris Banes 430a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes // Update our child view offset helpers 431a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes for (int i = 0, z = getChildCount(); i < z; i++) { 43279208cc336926148978ccb49861f986fada745e0Chris Banes final View child = getChildAt(i); 43379208cc336926148978ccb49861f986fada745e0Chris Banes 43479208cc336926148978ccb49861f986fada745e0Chris Banes if (mLastInsets != null && !ViewCompat.getFitsSystemWindows(child)) { 43579208cc336926148978ccb49861f986fada745e0Chris Banes final int insetTop = mLastInsets.getSystemWindowInsetTop(); 43679208cc336926148978ccb49861f986fada745e0Chris Banes if (child.getTop() < insetTop) { 43779208cc336926148978ccb49861f986fada745e0Chris Banes // If the child isn't set to fit system windows but is drawing within the inset 43879208cc336926148978ccb49861f986fada745e0Chris Banes // offset it down 43917ed3263761329f6aa6796941358c41001fff325Chris Banes ViewCompat.offsetTopAndBottom(child, insetTop); 44079208cc336926148978ccb49861f986fada745e0Chris Banes } 44179208cc336926148978ccb49861f986fada745e0Chris Banes } 44279208cc336926148978ccb49861f986fada745e0Chris Banes 44379208cc336926148978ccb49861f986fada745e0Chris Banes getViewOffsetHelper(child).onViewLayout(); 444a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 445a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 446a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes // Finally, set our minimum height to enable proper AppBarLayout collapsing 44779208cc336926148978ccb49861f986fada745e0Chris Banes if (mToolbar != null) { 4481701feace5652372dd2fe1913f74169a12e2c940Chris Banes if (mCollapsingTitleEnabled && TextUtils.isEmpty(mCollapsingTextHelper.getText())) { 44931075a61da61f1f0184ee909a70b1efcd7cee807Chris Banes // If we do not currently have a title, try and grab it from the Toolbar 45031075a61da61f1f0184ee909a70b1efcd7cee807Chris Banes mCollapsingTextHelper.setText(mToolbar.getTitle()); 45131075a61da61f1f0184ee909a70b1efcd7cee807Chris Banes } 4524837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes if (mToolbarDirectChild == null || mToolbarDirectChild == this) { 4534837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes setMinimumHeight(getHeightWithMargins(mToolbar)); 4544837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes } else { 4554837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes setMinimumHeight(getHeightWithMargins(mToolbarDirectChild)); 4564837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes } 4574837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes } 4584837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes } 4594837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes 4604837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes private static int getHeightWithMargins(@NonNull final View view) { 4614837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes final ViewGroup.LayoutParams lp = view.getLayoutParams(); 4624837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes if (lp instanceof MarginLayoutParams) { 4634837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes final MarginLayoutParams mlp = (MarginLayoutParams) lp; 4644837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes return view.getHeight() + mlp.topMargin + mlp.bottomMargin; 46579208cc336926148978ccb49861f986fada745e0Chris Banes } 4664837e2d38e11a8e85a2718e4620f73d32dcde184Chris Banes return view.getHeight(); 467a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 468a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 469a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes private static ViewOffsetHelper getViewOffsetHelper(View view) { 470a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes ViewOffsetHelper offsetHelper = (ViewOffsetHelper) view.getTag(R.id.view_offset_helper); 471a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes if (offsetHelper == null) { 472a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes offsetHelper = new ViewOffsetHelper(view); 473a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes view.setTag(R.id.view_offset_helper, offsetHelper); 474a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 475a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes return offsetHelper; 476a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 477a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 478a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes /** 4791701feace5652372dd2fe1913f74169a12e2c940Chris Banes * Sets the title to be displayed by this view, if enabled. 480a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * 4811701feace5652372dd2fe1913f74169a12e2c940Chris Banes * @see #setTitleEnabled(boolean) 4821701feace5652372dd2fe1913f74169a12e2c940Chris Banes * @see #getTitle() 4831701feace5652372dd2fe1913f74169a12e2c940Chris Banes * 4841701feace5652372dd2fe1913f74169a12e2c940Chris Banes * @attr ref R.styleable#CollapsingToolbarLayout_title 485a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes */ 4861701feace5652372dd2fe1913f74169a12e2c940Chris Banes public void setTitle(@Nullable CharSequence title) { 487a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes mCollapsingTextHelper.setText(title); 488a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 489a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 4901701feace5652372dd2fe1913f74169a12e2c940Chris Banes /** 4911701feace5652372dd2fe1913f74169a12e2c940Chris Banes * Returns the title currently being displayed by this view. If the title is not enabled, then 4921701feace5652372dd2fe1913f74169a12e2c940Chris Banes * this will return {@code null}. 4931701feace5652372dd2fe1913f74169a12e2c940Chris Banes * 4941701feace5652372dd2fe1913f74169a12e2c940Chris Banes * @attr ref R.styleable#CollapsingToolbarLayout_title 4951701feace5652372dd2fe1913f74169a12e2c940Chris Banes */ 4961701feace5652372dd2fe1913f74169a12e2c940Chris Banes @Nullable 4971701feace5652372dd2fe1913f74169a12e2c940Chris Banes public CharSequence getTitle() { 4981701feace5652372dd2fe1913f74169a12e2c940Chris Banes return mCollapsingTitleEnabled ? mCollapsingTextHelper.getText() : null; 4991701feace5652372dd2fe1913f74169a12e2c940Chris Banes } 5001701feace5652372dd2fe1913f74169a12e2c940Chris Banes 5011701feace5652372dd2fe1913f74169a12e2c940Chris Banes /** 5021701feace5652372dd2fe1913f74169a12e2c940Chris Banes * Sets whether this view should display its own title. 5031701feace5652372dd2fe1913f74169a12e2c940Chris Banes * 5041701feace5652372dd2fe1913f74169a12e2c940Chris Banes * <p>The title displayed by this view will shrink and grow based on the scroll offset.</p> 5051701feace5652372dd2fe1913f74169a12e2c940Chris Banes * 5061701feace5652372dd2fe1913f74169a12e2c940Chris Banes * @see #setTitle(CharSequence) 5071701feace5652372dd2fe1913f74169a12e2c940Chris Banes * @see #isTitleEnabled() 5081701feace5652372dd2fe1913f74169a12e2c940Chris Banes * 5091701feace5652372dd2fe1913f74169a12e2c940Chris Banes * @attr ref R.styleable#CollapsingToolbarLayout_titleEnabled 5101701feace5652372dd2fe1913f74169a12e2c940Chris Banes */ 5111701feace5652372dd2fe1913f74169a12e2c940Chris Banes public void setTitleEnabled(boolean enabled) { 5121701feace5652372dd2fe1913f74169a12e2c940Chris Banes if (enabled != mCollapsingTitleEnabled) { 5131701feace5652372dd2fe1913f74169a12e2c940Chris Banes mCollapsingTitleEnabled = enabled; 5141701feace5652372dd2fe1913f74169a12e2c940Chris Banes updateDummyView(); 5151701feace5652372dd2fe1913f74169a12e2c940Chris Banes requestLayout(); 5161701feace5652372dd2fe1913f74169a12e2c940Chris Banes } 5171701feace5652372dd2fe1913f74169a12e2c940Chris Banes } 5181701feace5652372dd2fe1913f74169a12e2c940Chris Banes 5191701feace5652372dd2fe1913f74169a12e2c940Chris Banes /** 5201701feace5652372dd2fe1913f74169a12e2c940Chris Banes * Returns whether this view is currently displaying its own title. 5211701feace5652372dd2fe1913f74169a12e2c940Chris Banes * 5221701feace5652372dd2fe1913f74169a12e2c940Chris Banes * @see #setTitleEnabled(boolean) 5231701feace5652372dd2fe1913f74169a12e2c940Chris Banes * 5241701feace5652372dd2fe1913f74169a12e2c940Chris Banes * @attr ref R.styleable#CollapsingToolbarLayout_titleEnabled 5251701feace5652372dd2fe1913f74169a12e2c940Chris Banes */ 5261701feace5652372dd2fe1913f74169a12e2c940Chris Banes public boolean isTitleEnabled() { 5271701feace5652372dd2fe1913f74169a12e2c940Chris Banes return mCollapsingTitleEnabled; 5281701feace5652372dd2fe1913f74169a12e2c940Chris Banes } 5291701feace5652372dd2fe1913f74169a12e2c940Chris Banes 530e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes /** 531e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes * Set whether the content scrim and/or status bar scrim should be shown or not. Any change 532e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes * in the vertical scroll may overwrite this value. Any visibility change will be animated if 533e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes * this view has already been laid out. 534e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes * 535e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes * @param shown whether the scrims should be shown 536e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes * 537e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes * @see #getStatusBarScrim() 538e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes * @see #getContentScrim() 539e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes */ 540e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes public void setScrimsShown(boolean shown) { 541e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes setScrimsShown(shown, ViewCompat.isLaidOut(this) && !isInEditMode()); 542a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 543a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 544e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes /** 545e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes * Set whether the content scrim and/or status bar scrim should be shown or not. Any change 546e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes * in the vertical scroll may overwrite this value. 547e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes * 548e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes * @param shown whether the scrims should be shown 549e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes * @param animate whether to animate the visibility change 550e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes * 551e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes * @see #getStatusBarScrim() 552e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes * @see #getContentScrim() 553e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes */ 554e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes public void setScrimsShown(boolean shown, boolean animate) { 555e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes if (mScrimsAreShown != shown) { 556e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes if (animate) { 557e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes animateScrim(shown ? 0xFF : 0x0); 5582b4b6274ed8c85c98489f67ddc8b7410c218e289Jens Ole Lauridsen } else { 559e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes setScrimAlpha(shown ? 0xFF : 0x0); 5602b4b6274ed8c85c98489f67ddc8b7410c218e289Jens Ole Lauridsen } 561e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes mScrimsAreShown = shown; 562f44e88b81821e61a65886cc7027617ca8995070bChris Banes } 563f44e88b81821e61a65886cc7027617ca8995070bChris Banes } 564f44e88b81821e61a65886cc7027617ca8995070bChris Banes 565f44e88b81821e61a65886cc7027617ca8995070bChris Banes private void animateScrim(int targetAlpha) { 56679208cc336926148978ccb49861f986fada745e0Chris Banes ensureToolbar(); 567f44e88b81821e61a65886cc7027617ca8995070bChris Banes if (mScrimAnimator == null) { 568f44e88b81821e61a65886cc7027617ca8995070bChris Banes mScrimAnimator = ViewUtils.createAnimator(); 5696df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes mScrimAnimator.setDuration(mScrimAnimationDuration); 5703a30d0eaba58dd961cf2ae9be3a7d0b9754a031eChris Banes mScrimAnimator.setInterpolator( 5713a30d0eaba58dd961cf2ae9be3a7d0b9754a031eChris Banes targetAlpha > mScrimAlpha 5723a30d0eaba58dd961cf2ae9be3a7d0b9754a031eChris Banes ? AnimationUtils.FAST_OUT_LINEAR_IN_INTERPOLATOR 5733a30d0eaba58dd961cf2ae9be3a7d0b9754a031eChris Banes : AnimationUtils.LINEAR_OUT_SLOW_IN_INTERPOLATOR); 574f44e88b81821e61a65886cc7027617ca8995070bChris Banes mScrimAnimator.setUpdateListener(new ValueAnimatorCompat.AnimatorUpdateListener() { 575f44e88b81821e61a65886cc7027617ca8995070bChris Banes @Override 576f44e88b81821e61a65886cc7027617ca8995070bChris Banes public void onAnimationUpdate(ValueAnimatorCompat animator) { 5772b4b6274ed8c85c98489f67ddc8b7410c218e289Jens Ole Lauridsen setScrimAlpha(animator.getAnimatedIntValue()); 57850dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes } 579f44e88b81821e61a65886cc7027617ca8995070bChris Banes }); 580f44e88b81821e61a65886cc7027617ca8995070bChris Banes } else if (mScrimAnimator.isRunning()) { 581f44e88b81821e61a65886cc7027617ca8995070bChris Banes mScrimAnimator.cancel(); 582f44e88b81821e61a65886cc7027617ca8995070bChris Banes } 583a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 5846ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes mScrimAnimator.setIntValues(mScrimAlpha, targetAlpha); 585f44e88b81821e61a65886cc7027617ca8995070bChris Banes mScrimAnimator.start(); 586a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 587a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 5882b4b6274ed8c85c98489f67ddc8b7410c218e289Jens Ole Lauridsen private void setScrimAlpha(int alpha) { 5892b4b6274ed8c85c98489f67ddc8b7410c218e289Jens Ole Lauridsen if (alpha != mScrimAlpha) { 5902b4b6274ed8c85c98489f67ddc8b7410c218e289Jens Ole Lauridsen final Drawable contentScrim = mContentScrim; 5912b4b6274ed8c85c98489f67ddc8b7410c218e289Jens Ole Lauridsen if (contentScrim != null && mToolbar != null) { 5922b4b6274ed8c85c98489f67ddc8b7410c218e289Jens Ole Lauridsen ViewCompat.postInvalidateOnAnimation(mToolbar); 5932b4b6274ed8c85c98489f67ddc8b7410c218e289Jens Ole Lauridsen } 5942b4b6274ed8c85c98489f67ddc8b7410c218e289Jens Ole Lauridsen mScrimAlpha = alpha; 5952b4b6274ed8c85c98489f67ddc8b7410c218e289Jens Ole Lauridsen ViewCompat.postInvalidateOnAnimation(CollapsingToolbarLayout.this); 5962b4b6274ed8c85c98489f67ddc8b7410c218e289Jens Ole Lauridsen } 5972b4b6274ed8c85c98489f67ddc8b7410c218e289Jens Ole Lauridsen } 5982b4b6274ed8c85c98489f67ddc8b7410c218e289Jens Ole Lauridsen 599a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes /** 6006ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * Set the drawable to use for the content scrim from resources. Providing null will disable 6016ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * the scrim functionality. 602a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * 6036ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @param drawable the drawable to display 604a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * 6056ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @attr ref R.styleable#CollapsingToolbarLayout_contentScrim 6066ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @see #getContentScrim() 607a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes */ 6086ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes public void setContentScrim(@Nullable Drawable drawable) { 6096ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes if (mContentScrim != drawable) { 6106ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes if (mContentScrim != null) { 6116ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes mContentScrim.setCallback(null); 6126ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes } 613bcb330de0c625b371010bada2a51363fc37b52ccChris Banes mContentScrim = drawable != null ? drawable.mutate() : null; 614bcb330de0c625b371010bada2a51363fc37b52ccChris Banes if (mContentScrim != null) { 615bcb330de0c625b371010bada2a51363fc37b52ccChris Banes mContentScrim.setBounds(0, 0, getWidth(), getHeight()); 616bcb330de0c625b371010bada2a51363fc37b52ccChris Banes mContentScrim.setCallback(this); 617bcb330de0c625b371010bada2a51363fc37b52ccChris Banes mContentScrim.setAlpha(mScrimAlpha); 618e9f1ca9247c94f9073403fd6777403ae5b94e77aChris Banes } 6196ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes ViewCompat.postInvalidateOnAnimation(this); 6206ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes } 621a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 622a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 623a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes /** 6246ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * Set the color to use for the content scrim. 625a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * 6266ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @param color the color to display 627a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * 6286ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @attr ref R.styleable#CollapsingToolbarLayout_contentScrim 6296ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @see #getContentScrim() 630a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes */ 6311701feace5652372dd2fe1913f74169a12e2c940Chris Banes public void setContentScrimColor(@ColorInt int color) { 6326ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes setContentScrim(new ColorDrawable(color)); 633a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 634a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 635a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes /** 6366ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * Set the drawable to use for the content scrim from resources. 637a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * 6386ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @param resId drawable resource id 6396ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * 6406ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @attr ref R.styleable#CollapsingToolbarLayout_contentScrim 6416ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @see #getContentScrim() 642a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes */ 6436ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes public void setContentScrimResource(@DrawableRes int resId) { 6446ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes setContentScrim(ContextCompat.getDrawable(getContext(), resId)); 6456ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes 6466ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes } 6476ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes 6486ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes /** 6496ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * Returns the drawable which is used for the foreground scrim. 6506ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * 6516ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @attr ref R.styleable#CollapsingToolbarLayout_contentScrim 6526ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @see #setContentScrim(Drawable) 6536ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes */ 654bcb330de0c625b371010bada2a51363fc37b52ccChris Banes @Nullable 6556ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes public Drawable getContentScrim() { 6566ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes return mContentScrim; 6576ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes } 6586ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes 6596ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes /** 6606ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * Set the drawable to use for the status bar scrim from resources. 6616ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * Providing null will disable the scrim functionality. 6626ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * 6636ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * <p>This scrim is only shown when we have been given a top system inset.</p> 6646ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * 6656ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @param drawable the drawable to display 6666ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * 6676ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @attr ref R.styleable#CollapsingToolbarLayout_statusBarScrim 6686ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @see #getStatusBarScrim() 6696ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes */ 6706ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes public void setStatusBarScrim(@Nullable Drawable drawable) { 6716ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes if (mStatusBarScrim != drawable) { 6726ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes if (mStatusBarScrim != null) { 6736ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes mStatusBarScrim.setCallback(null); 6746ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes } 675bcb330de0c625b371010bada2a51363fc37b52ccChris Banes mStatusBarScrim = drawable != null ? drawable.mutate() : null; 676bcb330de0c625b371010bada2a51363fc37b52ccChris Banes if (mStatusBarScrim != null) { 677bcb330de0c625b371010bada2a51363fc37b52ccChris Banes if (mStatusBarScrim.isStateful()) { 678bcb330de0c625b371010bada2a51363fc37b52ccChris Banes mStatusBarScrim.setState(getDrawableState()); 679bcb330de0c625b371010bada2a51363fc37b52ccChris Banes } 680bcb330de0c625b371010bada2a51363fc37b52ccChris Banes DrawableCompat.setLayoutDirection(mStatusBarScrim, 681bcb330de0c625b371010bada2a51363fc37b52ccChris Banes ViewCompat.getLayoutDirection(this)); 682bcb330de0c625b371010bada2a51363fc37b52ccChris Banes mStatusBarScrim.setVisible(getVisibility() == VISIBLE, false); 683bcb330de0c625b371010bada2a51363fc37b52ccChris Banes mStatusBarScrim.setCallback(this); 684bcb330de0c625b371010bada2a51363fc37b52ccChris Banes mStatusBarScrim.setAlpha(mScrimAlpha); 685bcb330de0c625b371010bada2a51363fc37b52ccChris Banes } 6866ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes ViewCompat.postInvalidateOnAnimation(this); 6876ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes } 6886ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes } 6896ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes 690bcb330de0c625b371010bada2a51363fc37b52ccChris Banes @Override 691bcb330de0c625b371010bada2a51363fc37b52ccChris Banes protected void drawableStateChanged() { 692bcb330de0c625b371010bada2a51363fc37b52ccChris Banes super.drawableStateChanged(); 693bcb330de0c625b371010bada2a51363fc37b52ccChris Banes 694bcb330de0c625b371010bada2a51363fc37b52ccChris Banes final int[] state = getDrawableState(); 695bcb330de0c625b371010bada2a51363fc37b52ccChris Banes boolean changed = false; 696bcb330de0c625b371010bada2a51363fc37b52ccChris Banes 697bcb330de0c625b371010bada2a51363fc37b52ccChris Banes Drawable d = mStatusBarScrim; 698bcb330de0c625b371010bada2a51363fc37b52ccChris Banes if (d != null && d.isStateful()) { 699bcb330de0c625b371010bada2a51363fc37b52ccChris Banes changed |= d.setState(state); 700bcb330de0c625b371010bada2a51363fc37b52ccChris Banes } 701bcb330de0c625b371010bada2a51363fc37b52ccChris Banes d = mContentScrim; 702bcb330de0c625b371010bada2a51363fc37b52ccChris Banes if (d != null && d.isStateful()) { 703bcb330de0c625b371010bada2a51363fc37b52ccChris Banes changed |= d.setState(state); 704bcb330de0c625b371010bada2a51363fc37b52ccChris Banes } 705bcb330de0c625b371010bada2a51363fc37b52ccChris Banes 706bcb330de0c625b371010bada2a51363fc37b52ccChris Banes if (changed) { 707bcb330de0c625b371010bada2a51363fc37b52ccChris Banes invalidate(); 708bcb330de0c625b371010bada2a51363fc37b52ccChris Banes } 709bcb330de0c625b371010bada2a51363fc37b52ccChris Banes } 710bcb330de0c625b371010bada2a51363fc37b52ccChris Banes 711bcb330de0c625b371010bada2a51363fc37b52ccChris Banes @Override 712bcb330de0c625b371010bada2a51363fc37b52ccChris Banes protected boolean verifyDrawable(Drawable who) { 713bcb330de0c625b371010bada2a51363fc37b52ccChris Banes return super.verifyDrawable(who) || who == mContentScrim || who == mStatusBarScrim; 714bcb330de0c625b371010bada2a51363fc37b52ccChris Banes } 715bcb330de0c625b371010bada2a51363fc37b52ccChris Banes 716bcb330de0c625b371010bada2a51363fc37b52ccChris Banes @Override 717bcb330de0c625b371010bada2a51363fc37b52ccChris Banes public void setVisibility(int visibility) { 718bcb330de0c625b371010bada2a51363fc37b52ccChris Banes super.setVisibility(visibility); 719bcb330de0c625b371010bada2a51363fc37b52ccChris Banes 720bcb330de0c625b371010bada2a51363fc37b52ccChris Banes final boolean visible = visibility == VISIBLE; 721bcb330de0c625b371010bada2a51363fc37b52ccChris Banes if (mStatusBarScrim != null && mStatusBarScrim.isVisible() != visible) { 722bcb330de0c625b371010bada2a51363fc37b52ccChris Banes mStatusBarScrim.setVisible(visible, false); 723bcb330de0c625b371010bada2a51363fc37b52ccChris Banes } 724bcb330de0c625b371010bada2a51363fc37b52ccChris Banes if (mContentScrim != null && mContentScrim.isVisible() != visible) { 725bcb330de0c625b371010bada2a51363fc37b52ccChris Banes mContentScrim.setVisible(visible, false); 726bcb330de0c625b371010bada2a51363fc37b52ccChris Banes } 727bcb330de0c625b371010bada2a51363fc37b52ccChris Banes } 728bcb330de0c625b371010bada2a51363fc37b52ccChris Banes 7296ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes /** 7306ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * Set the color to use for the status bar scrim. 7316ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * 7326ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * <p>This scrim is only shown when we have been given a top system inset.</p> 7336ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * 7346ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @param color the color to display 7356ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * 7366ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @attr ref R.styleable#CollapsingToolbarLayout_statusBarScrim 7376ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @see #getStatusBarScrim() 7386ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes */ 7391701feace5652372dd2fe1913f74169a12e2c940Chris Banes public void setStatusBarScrimColor(@ColorInt int color) { 7406ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes setStatusBarScrim(new ColorDrawable(color)); 7416ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes } 7426ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes 7436ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes /** 7446ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * Set the drawable to use for the content scrim from resources. 7456ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * 7466ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @param resId drawable resource id 7476ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * 7486ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @attr ref R.styleable#CollapsingToolbarLayout_statusBarScrim 7496ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @see #getStatusBarScrim() 7506ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes */ 7516ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes public void setStatusBarScrimResource(@DrawableRes int resId) { 7526ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes setStatusBarScrim(ContextCompat.getDrawable(getContext(), resId)); 7536ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes } 7546ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes 7556ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes /** 7566ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * Returns the drawable which is used for the status bar scrim. 7576ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * 7586ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @attr ref R.styleable#CollapsingToolbarLayout_statusBarScrim 7596ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes * @see #setStatusBarScrim(Drawable) 7606ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes */ 761bcb330de0c625b371010bada2a51363fc37b52ccChris Banes @Nullable 7626ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes public Drawable getStatusBarScrim() { 7636ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes return mStatusBarScrim; 764a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 765a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 766a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes /** 767a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * Sets the text color and size for the collapsed title from the specified 768a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * TextAppearance resource. 769a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * 770a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_collapsedTitleTextAppearance 771a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes */ 7721701feace5652372dd2fe1913f74169a12e2c940Chris Banes public void setCollapsedTitleTextAppearance(@StyleRes int resId) { 773a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes mCollapsingTextHelper.setCollapsedTextAppearance(resId); 774a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 775a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 776a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes /** 777a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * Sets the text color of the collapsed title. 778a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * 779a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * @param color The new text color in ARGB format 780a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes */ 7811701feace5652372dd2fe1913f74169a12e2c940Chris Banes public void setCollapsedTitleTextColor(@ColorInt int color) { 782a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes mCollapsingTextHelper.setCollapsedTextColor(color); 783a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 784a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 785a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes /** 7865c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes * Sets the horizontal alignment of the collapsed title and the vertical gravity that will 7875c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes * be used when there is extra space in the collapsed bounds beyond what is required for 7885c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes * the title itself. 7895c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes * 7905c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_collapsedTitleGravity 7915c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes */ 7925c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes public void setCollapsedTitleGravity(int gravity) { 793cd7313d4cdb81d0abaf9dc7aefc6ebadea899ab5Chris Banes mCollapsingTextHelper.setCollapsedTextGravity(gravity); 7945c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes } 7955c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes 7965c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes /** 7975c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes * Returns the horizontal and vertical alignment for title when collapsed. 7985c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes * 7995c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_collapsedTitleGravity 8005c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes */ 8015c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes public int getCollapsedTitleGravity() { 8025c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes return mCollapsingTextHelper.getCollapsedTextGravity(); 8035c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes } 8045c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes 8055c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes /** 806a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * Sets the text color and size for the expanded title from the specified 807a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * TextAppearance resource. 808a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * 809a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_expandedTitleTextAppearance 810a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes */ 8111701feace5652372dd2fe1913f74169a12e2c940Chris Banes public void setExpandedTitleTextAppearance(@StyleRes int resId) { 812a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes mCollapsingTextHelper.setExpandedTextAppearance(resId); 813a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 814a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 815a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes /** 816a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * Sets the text color of the expanded title. 817a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * 818a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * @param color The new text color in ARGB format 819a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes */ 8201701feace5652372dd2fe1913f74169a12e2c940Chris Banes public void setExpandedTitleColor(@ColorInt int color) { 821a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes mCollapsingTextHelper.setExpandedTextColor(color); 822a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 823a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 8246ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes /** 8255c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes * Sets the horizontal alignment of the expanded title and the vertical gravity that will 8265c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes * be used when there is extra space in the expanded bounds beyond what is required for 8275c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes * the title itself. 8285c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes * 8295c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_expandedTitleGravity 8305c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes */ 8315c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes public void setExpandedTitleGravity(int gravity) { 8325c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes mCollapsingTextHelper.setExpandedTextGravity(gravity); 8335c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes } 8345c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes 8355c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes /** 8365c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes * Returns the horizontal and vertical alignment for title when expanded. 8375c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes * 8385c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_expandedTitleGravity 8395c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes */ 8405c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes public int getExpandedTitleGravity() { 8415c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes return mCollapsingTextHelper.getExpandedTextGravity(); 8425c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes } 8435c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes 8445c7d7bbceeaebc46dc2e4b2135cc330414f716d4Chris Banes /** 845d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes * Set the typeface to use for the collapsed title. 846d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes * 847d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes * @param typeface typeface to use, or {@code null} to use the default. 848d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes */ 849d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes public void setCollapsedTitleTypeface(@Nullable Typeface typeface) { 850d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes mCollapsingTextHelper.setCollapsedTypeface(typeface); 851d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes } 852d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes 853d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes /** 854d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes * Returns the typeface used for the collapsed title. 855d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes */ 856d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes @NonNull 857d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes public Typeface getCollapsedTitleTypeface() { 858d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes return mCollapsingTextHelper.getCollapsedTypeface(); 859d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes } 860d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes 861d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes /** 862d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes * Set the typeface to use for the expanded title. 863d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes * 864d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes * @param typeface typeface to use, or {@code null} to use the default. 865d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes */ 866d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes public void setExpandedTitleTypeface(@Nullable Typeface typeface) { 867d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes mCollapsingTextHelper.setExpandedTypeface(typeface); 868d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes } 869d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes 870d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes /** 871d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes * Returns the typeface used for the expanded title. 872d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes */ 873d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes @NonNull 874d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes public Typeface getExpandedTitleTypeface() { 875d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes return mCollapsingTextHelper.getExpandedTypeface(); 876d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes } 877d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes 878d29e79fa09f428c510d1d9ca758dbda35a323f71Chris Banes /** 87934550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * Sets the expanded title margins. 88034550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * 88134550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @param start the starting title margin in pixels 88234550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @param top the top title margin in pixels 88334550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @param end the ending title margin in pixels 88434550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @param bottom the bottom title margin in pixels 88534550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * 88634550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @see #getExpandedTitleMarginStart() 88734550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @see #getExpandedTitleMarginTop() 88834550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @see #getExpandedTitleMarginEnd() 88934550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @see #getExpandedTitleMarginBottom() 89034550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_expandedTitleMargin 89134550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes */ 89234550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes public void setExpandedTitleMargin(int start, int top, int end, int bottom) { 89334550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes mExpandedMarginStart = start; 89434550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes mExpandedMarginTop = top; 89534550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes mExpandedMarginEnd = end; 89634550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes mExpandedMarginBottom = bottom; 89734550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes requestLayout(); 89834550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes } 89934550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes 90034550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes /** 90134550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @return the starting expanded title margin in pixels 90234550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * 90334550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @see #setExpandedTitleMarginStart(int) 90434550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_expandedTitleMarginStart 90534550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes */ 90634550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes public int getExpandedTitleMarginStart() { 90734550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes return mExpandedMarginStart; 90834550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes } 90934550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes 91034550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes /** 91134550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * Sets the starting expanded title margin in pixels. 91234550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * 91334550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @param margin the starting title margin in pixels 91434550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @see #getExpandedTitleMarginStart() 91534550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_expandedTitleMarginStart 91634550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes */ 91734550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes public void setExpandedTitleMarginStart(int margin) { 91834550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes mExpandedMarginStart = margin; 91934550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes requestLayout(); 92034550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes } 92134550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes 92234550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes /** 92334550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @return the top expanded title margin in pixels 92434550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @see #setExpandedTitleMarginTop(int) 92534550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_expandedTitleMarginTop 92634550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes */ 92734550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes public int getExpandedTitleMarginTop() { 92834550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes return mExpandedMarginTop; 92934550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes } 93034550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes 93134550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes /** 93234550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * Sets the top expanded title margin in pixels. 93334550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * 93434550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @param margin the top title margin in pixels 93534550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @see #getExpandedTitleMarginTop() 93634550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_expandedTitleMarginTop 93734550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes */ 93834550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes public void setExpandedTitleMarginTop(int margin) { 93934550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes mExpandedMarginTop = margin; 94034550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes requestLayout(); 94134550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes } 94234550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes 94334550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes /** 94434550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @return the ending expanded title margin in pixels 94534550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @see #setExpandedTitleMarginEnd(int) 94634550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_expandedTitleMarginEnd 94734550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes */ 94834550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes public int getExpandedTitleMarginEnd() { 94934550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes return mExpandedMarginEnd; 95034550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes } 95134550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes 95234550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes /** 95334550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * Sets the ending expanded title margin in pixels. 95434550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * 95534550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @param margin the ending title margin in pixels 95634550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @see #getExpandedTitleMarginEnd() 95734550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_expandedTitleMarginEnd 95834550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes */ 95934550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes public void setExpandedTitleMarginEnd(int margin) { 96034550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes mExpandedMarginEnd = margin; 96134550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes requestLayout(); 96234550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes } 96334550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes 96434550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes /** 96534550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @return the bottom expanded title margin in pixels 96634550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @see #setExpandedTitleMarginBottom(int) 96734550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_expandedTitleMarginBottom 96834550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes */ 96934550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes public int getExpandedTitleMarginBottom() { 97034550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes return mExpandedMarginBottom; 97134550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes } 97234550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes 97334550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes /** 97434550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * Sets the bottom expanded title margin in pixels. 97534550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * 97634550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @param margin the bottom title margin in pixels 97734550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @see #getExpandedTitleMarginBottom() 97834550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_expandedTitleMarginBottom 97934550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes */ 98034550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes public void setExpandedTitleMarginBottom(int margin) { 98134550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes mExpandedMarginBottom = margin; 98234550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes requestLayout(); 98334550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes } 98434550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes 98534550bb9e60e8935f2007ffea069c5bacd971e36Chris Banes /** 9866df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes * Set the amount of visible height in pixels used to define when to trigger a scrim 9876df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes * visibility change. 9886df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes * 9896df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes * <p>If the visible height of this view is less than the given value, the scrims will be 9906df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes * made visible, otherwise they are hidden.</p> 9916df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes * 9926df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes * @param height value in pixels used to define when to trigger a scrim visibility change 9936df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes * 9946df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_scrimVisibleHeightTrigger 9956df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes */ 9966df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes public void setScrimVisibleHeightTrigger(@IntRange(from = 0) final int height) { 9976df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes if (mScrimVisibleHeightTrigger != height) { 9986df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes mScrimVisibleHeightTrigger = height; 9996df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes // Update the scrim visibilty 10006df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes updateScrimVisibility(); 10016df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes } 10026df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes } 10036df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes 10046df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes /** 10056df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes * Returns the amount of visible height in pixels used to define when to trigger a scrim 10066df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes * visibility change. 10076df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes * 10086df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes * @see #setScrimTriggerOffset(int) 10096df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes */ 10106df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes public int getScrimVisibleHeightTrigger() { 10116df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes if (mScrimVisibleHeightTrigger >= 0) { 10126df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes // If we have one explictly set, return it 10136df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes return mScrimVisibleHeightTrigger; 10146df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes } 10156df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes 10166df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes // Otherwise we'll use the default computed value 10176df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes final int insetTop = mLastInsets != null ? mLastInsets.getSystemWindowInsetTop() : 0; 10186df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes 10196df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes final int minHeight = ViewCompat.getMinimumHeight(this); 10206df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes if (minHeight > 0) { 10216df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes // If we have a minHeight set, lets use 2 * minHeight (capped at our height) 10226df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes return Math.min((minHeight * 2) + insetTop, getHeight()); 10236df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes } 10246df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes 10256df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes // If we reach here then we don't have a min height set. Instead we'll take a 10266df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes // guess at 1/3 of our height being visible 10276df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes return getHeight() / 3; 10286df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes } 10296df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes 10306df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes /** 10316df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes * Set the duration used for scrim visibility animations. 10326df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes * 10336df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes * @param duration the duration to use in milliseconds 10346df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes * 10356df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes * @attr ref android.support.design.R.styleable#CollapsingToolbarLayout_scrimAnimationDuration 10366df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes */ 10379ee6a3fbb89698ebd7c26d4a86e2892a37a0d87aAurimas Liutikas public void setScrimAnimationDuration(@IntRange(from = 0) final long duration) { 10386df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes mScrimAnimationDuration = duration; 10396df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes } 10406df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes 10416df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes /** 10426df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes * Returns the duration in milliseconds used for scrim visibility animations. 10436ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes */ 1044e852801f9258e00f89da48918b58a6e933643ab9Aurimas Liutikas public long getScrimAnimationDuration() { 10456df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes return mScrimAnimationDuration; 1046a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 1047a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 1048a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes @Override 1049a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { 1050a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes return p instanceof LayoutParams; 1051a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 1052a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 1053a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes @Override 1054a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes protected LayoutParams generateDefaultLayoutParams() { 1055a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes return new LayoutParams(super.generateDefaultLayoutParams()); 1056a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 1057a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 1058a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes @Override 1059a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes public FrameLayout.LayoutParams generateLayoutParams(AttributeSet attrs) { 1060a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes return new LayoutParams(getContext(), attrs); 1061a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 1062a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 1063a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes @Override 1064a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes protected FrameLayout.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { 1065a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes return new LayoutParams(p); 1066a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 1067a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 1068a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes public static class LayoutParams extends FrameLayout.LayoutParams { 1069a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 1070a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes private static final float DEFAULT_PARALLAX_MULTIPLIER = 0.5f; 1071a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 107250dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes /** @hide */ 107350dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes @IntDef({ 107450dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes COLLAPSE_MODE_OFF, 107550dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes COLLAPSE_MODE_PIN, 107650dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes COLLAPSE_MODE_PARALLAX 107750dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes }) 107850dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes @Retention(RetentionPolicy.SOURCE) 107950dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes @interface CollapseMode {} 108050dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes 1081a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes /** 1082a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * The view will act as normal with no collapsing behavior. 1083a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes */ 1084a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes public static final int COLLAPSE_MODE_OFF = 0; 1085a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 1086a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes /** 1087a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * The view will pin in place until it reaches the bottom of the 1088a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * {@link CollapsingToolbarLayout}. 1089a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes */ 1090a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes public static final int COLLAPSE_MODE_PIN = 1; 1091a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 1092a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes /** 1093a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * The view will scroll in a parallax fashion. See {@link #setParallaxMultiplier(float)} 1094a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * to change the multiplier used. 1095a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes */ 1096a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes public static final int COLLAPSE_MODE_PARALLAX = 2; 1097a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 1098a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes int mCollapseMode = COLLAPSE_MODE_OFF; 1099a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes float mParallaxMult = DEFAULT_PARALLAX_MULTIPLIER; 1100a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 1101a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes public LayoutParams(Context c, AttributeSet attrs) { 1102a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes super(c, attrs); 1103a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 1104a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes TypedArray a = c.obtainStyledAttributes(attrs, 1105c6cbbb50a06ec08e6888bd1c3dfd7fdf588d9db5Chris Banes R.styleable.CollapsingToolbarLayout_Layout); 1106a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes mCollapseMode = a.getInt( 1107c6cbbb50a06ec08e6888bd1c3dfd7fdf588d9db5Chris Banes R.styleable.CollapsingToolbarLayout_Layout_layout_collapseMode, 1108a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes COLLAPSE_MODE_OFF); 1109a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes setParallaxMultiplier(a.getFloat( 1110c6cbbb50a06ec08e6888bd1c3dfd7fdf588d9db5Chris Banes R.styleable.CollapsingToolbarLayout_Layout_layout_collapseParallaxMultiplier, 1111a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes DEFAULT_PARALLAX_MULTIPLIER)); 1112a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes a.recycle(); 1113a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 1114a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 1115a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes public LayoutParams(int width, int height) { 1116a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes super(width, height); 1117a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 1118a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 1119a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes public LayoutParams(int width, int height, int gravity) { 1120a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes super(width, height, gravity); 1121a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 1122a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 1123a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes public LayoutParams(ViewGroup.LayoutParams p) { 1124a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes super(p); 1125a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 1126a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 1127a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes public LayoutParams(MarginLayoutParams source) { 1128a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes super(source); 1129a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 1130a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 1131a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes public LayoutParams(FrameLayout.LayoutParams source) { 1132a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes super(source); 1133a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 1134a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 1135a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes /** 1136a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * Set the collapse mode. 1137a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * 1138a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * @param collapseMode one of {@link #COLLAPSE_MODE_OFF}, {@link #COLLAPSE_MODE_PIN} 1139a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * or {@link #COLLAPSE_MODE_PARALLAX}. 1140a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes */ 114150dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes public void setCollapseMode(@CollapseMode int collapseMode) { 1142a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes mCollapseMode = collapseMode; 1143a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 1144a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes 1145a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes /** 114650dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes * Returns the requested collapse mode. 114750dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes * 114850dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes * @return the current mode. One of {@link #COLLAPSE_MODE_OFF}, {@link #COLLAPSE_MODE_PIN} 114950dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes * or {@link #COLLAPSE_MODE_PARALLAX}. 115050dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes */ 115150dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes @CollapseMode 115250dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes public int getCollapseMode() { 115350dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes return mCollapseMode; 115450dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes } 115550dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes 115650dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes /** 115750dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes * Set the parallax scroll multiplier used in conjunction with 1158a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * {@link #COLLAPSE_MODE_PARALLAX}. A value of {@code 0.0} indicates no movement at all, 1159a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * {@code 1.0f} indicates normal scroll movement. 1160a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * 1161a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes * @param multiplier the multiplier. 116250dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes * 116350dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes * @see #getParallaxMultiplier() 1164a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes */ 1165a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes public void setParallaxMultiplier(float multiplier) { 1166a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes mParallaxMult = multiplier; 1167a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 116850dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes 116950dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes /** 117050dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes * Returns the parallax scroll multiplier used in conjunction with 117150dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes * {@link #COLLAPSE_MODE_PARALLAX}. 117250dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes * 117350dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes * @see #setParallaxMultiplier(float) 117450dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes */ 117550dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes public float getParallaxMultiplier() { 117650dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes return mParallaxMult; 117750dfc33a565c4aefe6d5e844c93aa24a74cb80b3Chris Banes } 1178a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes } 1179631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes 11806df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes /** 11816df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes * Show or hide the scrims if needed 11826df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes */ 11836df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes final void updateScrimVisibility() { 11846df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes if (mContentScrim != null || mStatusBarScrim != null) { 11856df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes setScrimsShown(getHeight() + mCurrentOffset < getScrimVisibleHeightTrigger()); 11866df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes } 11876df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes } 11886df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes 1189631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes private class OffsetUpdateListener implements AppBarLayout.OnOffsetChangedListener { 1190631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes @Override 1191631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes public void onOffsetChanged(AppBarLayout layout, int verticalOffset) { 11926ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes mCurrentOffset = verticalOffset; 11936ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes 11946ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes final int insetTop = mLastInsets != null ? mLastInsets.getSystemWindowInsetTop() : 0; 1195631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes 1196631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes for (int i = 0, z = getChildCount(); i < z; i++) { 1197631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes final View child = getChildAt(i); 1198631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 1199631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes final ViewOffsetHelper offsetHelper = getViewOffsetHelper(child); 1200631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes 1201631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes switch (lp.mCollapseMode) { 1202631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes case LayoutParams.COLLAPSE_MODE_PIN: 12036ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes if (getHeight() - insetTop + verticalOffset >= child.getHeight()) { 1204631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes offsetHelper.setTopAndBottomOffset(-verticalOffset); 1205631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes } 1206631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes break; 1207631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes case LayoutParams.COLLAPSE_MODE_PARALLAX: 1208631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes offsetHelper.setTopAndBottomOffset( 1209631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes Math.round(-verticalOffset * lp.mParallaxMult)); 1210631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes break; 1211631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes } 1212631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes } 1213631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes 12146ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes // Show or hide the scrims if needed 12156df5bb9903307734ed05a5135c7812fb9b6d43c8Chris Banes updateScrimVisibility(); 1216631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes 12176ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes if (mStatusBarScrim != null && insetTop > 0) { 12186ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes ViewCompat.postInvalidateOnAnimation(CollapsingToolbarLayout.this); 12196ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes } 12206ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes 1221631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes // Update the collapsing text's fraction 1222631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes final int expandRange = getHeight() - ViewCompat.getMinimumHeight( 12236ba61c5c79fe025036593c9daf79cb65299bb0b6Chris Banes CollapsingToolbarLayout.this) - insetTop; 1224631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes mCollapsingTextHelper.setExpansionFraction( 1225631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes Math.abs(verticalOffset) / (float) expandRange); 1226631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes } 1227631f64ec9c6255f38a7f746d7949b6a537c1180fChris Banes } 1228a6a508b2296730ca6954aaebcca52a9962a5cb55Chris Banes} 1229