1bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell/* 2bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * Copyright (C) 2012 The Android Open Source Project 3bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * 4bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * Licensed under the Apache License, Version 2.0 (the "License"); 5bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * you may not use this file except in compliance with the License. 6bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * You may obtain a copy of the License at 7bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * 8bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * http://www.apache.org/licenses/LICENSE-2.0 9bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * 10bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * Unless required by applicable law or agreed to in writing, software 11bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * distributed under the License is distributed on an "AS IS" BASIS, 12bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * See the License for the specific language governing permissions and 14bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * limitations under the License. 15bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell */ 16bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 1766698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banespackage android.support.v7.widget; 18bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 198e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikasimport static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP; 208e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas 21fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikasimport android.animation.Animator; 22fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikasimport android.animation.AnimatorListenerAdapter; 23bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.Context; 2449c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.content.res.Configuration; 25bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.res.TypedArray; 2649c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.graphics.Canvas; 27bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.graphics.Rect; 2849c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.graphics.drawable.Drawable; 2949c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.os.Build; 3049c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.os.Parcelable; 31c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viveretteimport android.support.annotation.RestrictTo; 32fa4c72b658085b888c94688d6882e66eabc50e25Chris Banesimport android.support.v4.view.NestedScrollingParent; 33fa4c72b658085b888c94688d6882e66eabc50e25Chris Banesimport android.support.v4.view.NestedScrollingParentHelper; 3449c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.view.ViewCompat; 35ee322d85233b857047ba629a2456adc0b0392b4bChris Banesimport android.support.v7.app.AppCompatDelegate; 36d900fe072335d488f883585e3f686ef955d1ccc9Chris Banesimport android.support.v7.appcompat.R; 3766698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.view.menu.MenuPresenter; 38bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.util.AttributeSet; 3949c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.util.SparseArray; 4049c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.Menu; 41bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.View; 4249c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.ViewGroup; 43fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikasimport android.view.ViewPropertyAnimator; 4449c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.Window; 453035be16658d7652fdc472f971c81d8f7ffb60fdAurimas Liutikasimport android.widget.OverScroller; 46bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 47bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell/** 4820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Special layout for the containing of an overlay action bar (and its content) to correctly handle 4920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * fitting system windows when the content has request that its layout ignore them. 5089208232f3b5d1451408d787872504a190bc7ee0Chris Banes * 5189208232f3b5d1451408d787872504a190bc7ee0Chris Banes * @hide 52bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell */ 538e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas@RestrictTo(LIBRARY_GROUP) 54fa4c72b658085b888c94688d6882e66eabc50e25Chris Banespublic class ActionBarOverlayLayout extends ViewGroup implements DecorContentParent, 55fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes NestedScrollingParent { 5649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private static final String TAG = "ActionBarOverlayLayout"; 5720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 5820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private int mActionBarHeight; 5949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes //private WindowDecorActionBar mActionBar; 6049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private int mWindowVisibility = View.VISIBLE; 6149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 6249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // The main UI elements that we handle the layout of. 6349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private ContentFrameLayout mContent; 642c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas ActionBarContainer mActionBarTop; 6549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 6649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Some interior UI elements. 6749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private DecorToolbar mDecorToolbar; 6849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 6949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Content overlay drawable - generally the action bar's shadow 7049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private Drawable mWindowContentOverlay; 7149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private boolean mIgnoreWindowContentOverlay; 7249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 7349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private boolean mOverlayMode; 7449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private boolean mHasNonEmbeddedTabs; 7549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private boolean mHideOnContentScroll; 762c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas boolean mAnimatingForFling; 7749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private int mHideOnContentScrollReference; 7849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private int mLastSystemUiVisibility; 7949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private final Rect mBaseContentInsets = new Rect(); 8049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private final Rect mLastBaseContentInsets = new Rect(); 8149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private final Rect mContentInsets = new Rect(); 8249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private final Rect mBaseInnerInsets = new Rect(); 83044757e817a79113607fd16ac04995d250798f95Ian Lake private final Rect mLastBaseInnerInsets = new Rect(); 8449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private final Rect mInnerInsets = new Rect(); 8549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private final Rect mLastInnerInsets = new Rect(); 8649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 8749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private ActionBarVisibilityCallback mActionBarVisibilityCallback; 8849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 8949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private final int ACTION_BAR_ANIMATE_DELAY = 600; // ms 9049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 913035be16658d7652fdc472f971c81d8f7ffb60fdAurimas Liutikas private OverScroller mFlingEstimator; 9249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 93fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas ViewPropertyAnimator mCurrentActionBarTopAnimator; 9449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 95fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas final AnimatorListenerAdapter mTopAnimatorListener = new AnimatorListenerAdapter() { 9649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 97fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas public void onAnimationEnd(Animator animator) { 9849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mCurrentActionBarTopAnimator = null; 9949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mAnimatingForFling = false; 10049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 10149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 10249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 103fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas public void onAnimationCancel(Animator animator) { 10449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mCurrentActionBarTopAnimator = null; 10549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mAnimatingForFling = false; 10649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 10749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes }; 10849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 10949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private final Runnable mRemoveActionBarHideOffset = new Runnable() { 110e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas @Override 11149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void run() { 11249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes haltActionBarHideOffsetAnimations(); 113fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas mCurrentActionBarTopAnimator = mActionBarTop.animate().translationY(0) 11449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes .setListener(mTopAnimatorListener); 11549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 11649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes }; 11749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 11849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private final Runnable mAddActionBarHideOffset = new Runnable() { 119e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas @Override 12049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void run() { 12149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes haltActionBarHideOffsetAnimations(); 122fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas mCurrentActionBarTopAnimator = mActionBarTop.animate() 12349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes .translationY(-mActionBarTop.getHeight()) 12449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes .setListener(mTopAnimatorListener); 12549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 12649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes }; 12749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 12849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes static final int[] ATTRS = new int [] { 12949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes R.attr.actionBarSize, 13049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes android.R.attr.windowContentOverlay 13120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns }; 13220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 133fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes private final NestedScrollingParentHelper mParentHelper; 134fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes 13520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public ActionBarOverlayLayout(Context context) { 136fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes this(context, null); 13720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 13820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 13920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public ActionBarOverlayLayout(Context context, AttributeSet attrs) { 14020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns super(context, attrs); 14120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns init(context); 142fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes 143fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes mParentHelper = new NestedScrollingParentHelper(this); 144bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 14520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 14620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private void init(Context context) { 14749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes TypedArray ta = getContext().getTheme().obtainStyledAttributes(ATTRS); 14820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mActionBarHeight = ta.getDimensionPixelSize(0, 0); 14949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mWindowContentOverlay = ta.getDrawable(1); 15049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setWillNotDraw(mWindowContentOverlay == null); 15120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ta.recycle(); 15249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 15349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mIgnoreWindowContentOverlay = context.getApplicationInfo().targetSdkVersion < 15449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes Build.VERSION_CODES.KITKAT; 15549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 1563035be16658d7652fdc472f971c81d8f7ffb60fdAurimas Liutikas mFlingEstimator = new OverScroller(context); 15749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 15849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 15949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 16049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected void onDetachedFromWindow() { 16149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super.onDetachedFromWindow(); 16249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes haltActionBarHideOffsetAnimations(); 16349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 16449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 16549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setActionBarVisibilityCallback(ActionBarVisibilityCallback cb) { 16649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionBarVisibilityCallback = cb; 16749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (getWindowToken() != null) { 16849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // This is being initialized after being added to a window; 16949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // make sure to update all state now. 17049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionBarVisibilityCallback.onWindowVisibilityChanged(mWindowVisibility); 17149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mLastSystemUiVisibility != 0) { 17249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int newVis = mLastSystemUiVisibility; 17349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes onWindowSystemUiVisibilityChanged(newVis); 17449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ViewCompat.requestApplyInsets(this); 17549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 17649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 17749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 17849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 17949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setOverlayMode(boolean overlayMode) { 18049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mOverlayMode = overlayMode; 18149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 18249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /* 18349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Drawing the window content overlay was broken before K so starting to draw it 18449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * again unexpectedly will cause artifacts in some apps. They should fix it. 18549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 18649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mIgnoreWindowContentOverlay = overlayMode && 18749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes getContext().getApplicationInfo().targetSdkVersion < 18849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes Build.VERSION_CODES.KITKAT; 189bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 19020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 19149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean isInOverlayMode() { 19249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mOverlayMode; 19349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 19449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 19549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setHasNonEmbeddedTabs(boolean hasNonEmbeddedTabs) { 19649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mHasNonEmbeddedTabs = hasNonEmbeddedTabs; 19749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 19849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 19949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setShowingForActionMode(boolean showing) { 20049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // TODO: Add workaround for this 20149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// if (showing) { 20249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// // Here's a fun hack: if the status bar is currently being hidden, 20349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// // and the application has asked for stable content insets, then 20449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// // we will end up with the action mode action bar being shown 20549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// // without the status bar, but moved below where the status bar 20649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// // would be. Not nice. Trying to have this be positioned 20749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// // correctly is not easy (basically we need yet *another* content 20849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// // inset from the window manager to know where to put it), so 20949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// // instead we will just temporarily force the status bar to be shown. 21049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// if ((getWindowSystemUiVisibility() & (SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 21149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// | SYSTEM_UI_FLAG_LAYOUT_STABLE)) 21249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// == (SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | SYSTEM_UI_FLAG_LAYOUT_STABLE)) { 21349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// setDisabledSystemUiVisibility(SYSTEM_UI_FLAG_FULLSCREEN); 21449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// } 21549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// } else { 21649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// setDisabledSystemUiVisibility(0); 21749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// } 21849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 21949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 220e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas @Override 22149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected void onConfigurationChanged(Configuration newConfig) { 22264dbe1d454f1190b3cd8426d09b9119949a10709Kirill Grouchnikov super.onConfigurationChanged(newConfig); 22349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes init(getContext()); 22449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ViewCompat.requestApplyInsets(this); 22549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 22649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 227e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas @Override 22849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void onWindowSystemUiVisibilityChanged(int visible) { 22949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (Build.VERSION.SDK_INT >= 16) { 23049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super.onWindowSystemUiVisibilityChanged(visible); 23149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 23249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 23349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int diff = mLastSystemUiVisibility ^ visible; 23449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mLastSystemUiVisibility = visible; 23549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final boolean barVisible = (visible & SYSTEM_UI_FLAG_FULLSCREEN) == 0; 23649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final boolean stable = (visible & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0; 23749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mActionBarVisibilityCallback != null) { 23849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // We want the bar to be visible if it is not being hidden, 23949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // or the app has not turned on a stable UI mode (meaning they 24049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // are performing explicit layout around the action bar). 24149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionBarVisibilityCallback.enableContentAnimations(!stable); 24249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (barVisible || !stable) mActionBarVisibilityCallback.showForSystem(); 24349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes else mActionBarVisibilityCallback.hideForSystem(); 24449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 24549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if ((diff & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0) { 24649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mActionBarVisibilityCallback != null) { 24749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ViewCompat.requestApplyInsets(this); 24849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 24949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 25049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 25149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 25249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 25349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected void onWindowVisibilityChanged(int visibility) { 25449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super.onWindowVisibilityChanged(visibility); 25549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mWindowVisibility = visibility; 25649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mActionBarVisibilityCallback != null) { 25749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionBarVisibilityCallback.onWindowVisibilityChanged(visibility); 25849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 259bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 26020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 26120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private boolean applyInsets(View view, Rect insets, boolean left, boolean top, 26220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns boolean bottom, boolean right) { 26320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns boolean changed = false; 26449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes LayoutParams lp = (LayoutParams)view.getLayoutParams(); 26520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (left && lp.leftMargin != insets.left) { 26620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns changed = true; 26720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns lp.leftMargin = insets.left; 26820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 26920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (top && lp.topMargin != insets.top) { 27020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns changed = true; 27120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns lp.topMargin = insets.top; 27220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 27320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (right && lp.rightMargin != insets.right) { 27420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns changed = true; 27520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns lp.rightMargin = insets.right; 27620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 27720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (bottom && lp.bottomMargin != insets.bottom) { 27820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns changed = true; 27920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns lp.bottomMargin = insets.bottom; 28020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 28120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return changed; 282bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 28320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 28426f676060f6b45921a809c696acceac9c031c85bChris Banes @Override 28526f676060f6b45921a809c696acceac9c031c85bChris Banes protected boolean fitSystemWindows(Rect insets) { 28626f676060f6b45921a809c696acceac9c031c85bChris Banes pullChildren(); 28726f676060f6b45921a809c696acceac9c031c85bChris Banes 28826f676060f6b45921a809c696acceac9c031c85bChris Banes final int vis = ViewCompat.getWindowSystemUiVisibility(this); 28926f676060f6b45921a809c696acceac9c031c85bChris Banes final boolean stable = (vis & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0; 29026f676060f6b45921a809c696acceac9c031c85bChris Banes final Rect systemInsets = insets; 29126f676060f6b45921a809c696acceac9c031c85bChris Banes 292acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes // The top action bar is always within the content area. 293ade8ff8ba125b7d370de9ef5033ccbe89b2a30ccChris Banes boolean changed = applyInsets(mActionBarTop, systemInsets, true, true, false, true); 29426f676060f6b45921a809c696acceac9c031c85bChris Banes 29526f676060f6b45921a809c696acceac9c031c85bChris Banes mBaseInnerInsets.set(systemInsets); 2961f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes ViewUtils.computeFitSystemWindows(this, mBaseInnerInsets, mBaseContentInsets); 297044757e817a79113607fd16ac04995d250798f95Ian Lake if (!mLastBaseInnerInsets.equals(mBaseInnerInsets)) { 298044757e817a79113607fd16ac04995d250798f95Ian Lake changed = true; 299044757e817a79113607fd16ac04995d250798f95Ian Lake mLastBaseInnerInsets.set(mBaseInnerInsets); 300044757e817a79113607fd16ac04995d250798f95Ian Lake } 30126f676060f6b45921a809c696acceac9c031c85bChris Banes if (!mLastBaseContentInsets.equals(mBaseContentInsets)) { 30226f676060f6b45921a809c696acceac9c031c85bChris Banes changed = true; 30326f676060f6b45921a809c696acceac9c031c85bChris Banes mLastBaseContentInsets.set(mBaseContentInsets); 30426f676060f6b45921a809c696acceac9c031c85bChris Banes } 30526f676060f6b45921a809c696acceac9c031c85bChris Banes 30626f676060f6b45921a809c696acceac9c031c85bChris Banes if (changed) { 30726f676060f6b45921a809c696acceac9c031c85bChris Banes requestLayout(); 30826f676060f6b45921a809c696acceac9c031c85bChris Banes } 30926f676060f6b45921a809c696acceac9c031c85bChris Banes 31026f676060f6b45921a809c696acceac9c031c85bChris Banes // We don't do any more at this point. To correctly compute the content/inner 31126f676060f6b45921a809c696acceac9c031c85bChris Banes // insets in all cases, we need to know the measured size of the various action 31226f676060f6b45921a809c696acceac9c031c85bChris Banes // bar elements. fitSystemWindows() happens before the measure pass, so we can't 31326f676060f6b45921a809c696acceac9c031c85bChris Banes // do that here. Instead we will take this up in onMeasure(). 31426f676060f6b45921a809c696acceac9c031c85bChris Banes return true; 31526f676060f6b45921a809c696acceac9c031c85bChris Banes } 31649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 31749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 31849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected LayoutParams generateDefaultLayoutParams() { 31949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 32049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 32149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 32249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 32349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public LayoutParams generateLayoutParams(AttributeSet attrs) { 32449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return new LayoutParams(getContext(), attrs); 32549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 32649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 32749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 32849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { 32949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return new LayoutParams(p); 33049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 33149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 33249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 33349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { 33449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return p instanceof LayoutParams; 33549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 33649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 33749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 33849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 33949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 34049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 34149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int maxHeight = 0; 34249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int maxWidth = 0; 34349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int childState = 0; 34449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 34549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int topInset = 0; 34649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int bottomInset = 0; 34749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 34849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes measureChildWithMargins(mActionBarTop, widthMeasureSpec, 0, heightMeasureSpec, 0); 34949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes LayoutParams lp = (LayoutParams) mActionBarTop.getLayoutParams(); 35049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxWidth = Math.max(maxWidth, 35149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionBarTop.getMeasuredWidth() + lp.leftMargin + lp.rightMargin); 35249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxHeight = Math.max(maxHeight, 35349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionBarTop.getMeasuredHeight() + lp.topMargin + lp.bottomMargin); 354fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas childState = View.combineMeasuredStates(childState, mActionBarTop.getMeasuredState()); 35549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 35649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int vis = ViewCompat.getWindowSystemUiVisibility(this); 35749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final boolean stable = (vis & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0; 35849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 35949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (stable) { 36049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // This is the standard space needed for the action bar. For stable measurement, 36149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // we can't depend on the size currently reported by it -- this must remain constant. 36249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes topInset = mActionBarHeight; 36349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mHasNonEmbeddedTabs) { 36449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final View tabs = mActionBarTop.getTabContainer(); 36549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (tabs != null) { 36649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // If tabs are not embedded, increase space on top to account for them. 36749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes topInset += mActionBarHeight; 36849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 36949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 37049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else if (mActionBarTop.getVisibility() != GONE) { 37149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // This is the space needed on top of the window for all of the action bar 37249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // and tabs. 37349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes topInset = mActionBarTop.getMeasuredHeight(); 37449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 37549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 37649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // If the window has not requested system UI layout flags, we need to 37749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // make sure its content is not being covered by system UI... though it 37849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // will still be covered by the action bar if they have requested it to 37949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // overlay. 38049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mContentInsets.set(mBaseContentInsets); 38149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mInnerInsets.set(mBaseInnerInsets); 38249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (!mOverlayMode && !stable) { 38349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mContentInsets.top += topInset; 38449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mContentInsets.bottom += bottomInset; 38549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 38649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mInnerInsets.top += topInset; 38749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mInnerInsets.bottom += bottomInset; 38849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 38949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes applyInsets(mContent, mContentInsets, true, true, true, true); 39049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 39149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (!mLastInnerInsets.equals(mInnerInsets)) { 39249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // If the inner insets have changed, we need to dispatch this down to 39349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // the app's fitSystemWindows(). We do this before measuring the content 39449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // view to keep the same semantics as the normal fitSystemWindows() call. 39549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mLastInnerInsets.set(mInnerInsets); 39649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 39749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mContent.dispatchFitSystemWindows(mInnerInsets); 39849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 39949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 40049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes measureChildWithMargins(mContent, widthMeasureSpec, 0, heightMeasureSpec, 0); 40149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes lp = (LayoutParams) mContent.getLayoutParams(); 40249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxWidth = Math.max(maxWidth, 40349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mContent.getMeasuredWidth() + lp.leftMargin + lp.rightMargin); 40449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxHeight = Math.max(maxHeight, 40549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mContent.getMeasuredHeight() + lp.topMargin + lp.bottomMargin); 406fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas childState = View.combineMeasuredStates(childState, mContent.getMeasuredState()); 40749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 40849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Account for padding too 40949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxWidth += getPaddingLeft() + getPaddingRight(); 41049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxHeight += getPaddingTop() + getPaddingBottom(); 41149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 41249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Check against our minimum height and width 41349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight()); 41449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth()); 41549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 41649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setMeasuredDimension( 417fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas View.resolveSizeAndState(maxWidth, widthMeasureSpec, childState), 418fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas View.resolveSizeAndState(maxHeight, heightMeasureSpec, 41949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childState << MEASURED_HEIGHT_STATE_SHIFT)); 42049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 42149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 42249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 42349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 42449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int count = getChildCount(); 42549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 42649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int parentLeft = getPaddingLeft(); 42749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int parentRight = right - left - getPaddingRight(); 42849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 42949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int parentTop = getPaddingTop(); 43049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int parentBottom = bottom - top - getPaddingBottom(); 43149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 43249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes for (int i = 0; i < count; i++) { 43349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final View child = getChildAt(i); 43449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child.getVisibility() != GONE) { 43549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 43649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 43749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int width = child.getMeasuredWidth(); 43849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int height = child.getMeasuredHeight(); 43949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 44049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int childLeft = parentLeft + lp.leftMargin; 441acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes int childTop = parentTop + lp.topMargin; 44249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 44349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes child.layout(childLeft, childTop, childLeft + width, childTop + height); 44449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 44549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 44649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 44749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 44849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 44949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void draw(Canvas c) { 45049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super.draw(c); 45149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mWindowContentOverlay != null && !mIgnoreWindowContentOverlay) { 45249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int top = mActionBarTop.getVisibility() == VISIBLE ? 453fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas (int) (mActionBarTop.getBottom() + mActionBarTop.getTranslationY() + 0.5f) 45449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes : 0; 45549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mWindowContentOverlay.setBounds(0, top, getWidth(), 45649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes top + mWindowContentOverlay.getIntrinsicHeight()); 45749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mWindowContentOverlay.draw(c); 45849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 45949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 46049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 46149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 46249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean shouldDelayChildPressedState() { 46349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return false; 46449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 46549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 46649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 46749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean onStartNestedScroll(View child, View target, int axes) { 46849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if ((axes & SCROLL_AXIS_VERTICAL) == 0 || mActionBarTop.getVisibility() != VISIBLE) { 46949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return false; 47049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 47149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mHideOnContentScroll; 47249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 47349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 47449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 47549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void onNestedScrollAccepted(View child, View target, int axes) { 476fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes mParentHelper.onNestedScrollAccepted(child, target, axes); 47749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mHideOnContentScrollReference = getActionBarHideOffset(); 47849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes haltActionBarHideOffsetAnimations(); 47949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mActionBarVisibilityCallback != null) { 48049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionBarVisibilityCallback.onContentScrollStarted(); 48149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 48249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 48349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 48449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 48549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void onNestedScroll(View target, int dxConsumed, int dyConsumed, 48649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int dxUnconsumed, int dyUnconsumed) { 48749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mHideOnContentScrollReference += dyConsumed; 48849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setActionBarHideOffset(mHideOnContentScrollReference); 48949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 49049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 49149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 49249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void onStopNestedScroll(View target) { 49349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mHideOnContentScroll && !mAnimatingForFling) { 49449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mHideOnContentScrollReference <= mActionBarTop.getHeight()) { 49549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes postRemoveActionBarHideOffset(); 49649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 49749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes postAddActionBarHideOffset(); 49849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 49949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 50049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mActionBarVisibilityCallback != null) { 50149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionBarVisibilityCallback.onContentScrollStopped(); 50249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 50349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 50449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 50549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 50649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) { 50749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (!mHideOnContentScroll || !consumed) { 50849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return false; 50949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 51049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (shouldHideActionBarOnFling(velocityX, velocityY)) { 51149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes addActionBarHideOffset(); 51249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 51349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes removeActionBarHideOffset(); 51449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 51549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mAnimatingForFling = true; 51649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return true; 51749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 51849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 519fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes @Override 520fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) { 521fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes // no-op 522fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes } 523fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes 524fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes @Override 525fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes public boolean onNestedPreFling(View target, float velocityX, float velocityY) { 526fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes return false; 527fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes } 528fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes 529fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes @Override 530fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes public int getNestedScrollAxes() { 531fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes return mParentHelper.getNestedScrollAxes(); 532fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes } 533fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes 53420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns void pullChildren() { 53520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mContent == null) { 536fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mContent = findViewById(R.id.action_bar_activity_content); 537fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mActionBarTop = findViewById(R.id.action_bar_container); 53849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar = getDecorToolbar(findViewById(R.id.action_bar)); 53949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 54049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 54149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 54249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private DecorToolbar getDecorToolbar(View view) { 54349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (view instanceof DecorToolbar) { 54449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return (DecorToolbar) view; 54549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else if (view instanceof Toolbar) { 54649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return ((Toolbar) view).getWrapper(); 54749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 54849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes throw new IllegalStateException("Can't make a decor toolbar out of " + 54949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes view.getClass().getSimpleName()); 55049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 55149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 55249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 55349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setHideOnContentScrollEnabled(boolean hideOnContentScroll) { 55449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (hideOnContentScroll != mHideOnContentScroll) { 55549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mHideOnContentScroll = hideOnContentScroll; 55649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (!hideOnContentScroll) { 55749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes haltActionBarHideOffsetAnimations(); 55849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setActionBarHideOffset(0); 55949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 56049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 56149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 56249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 56349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean isHideOnContentScrollEnabled() { 56449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mHideOnContentScroll; 56549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 56649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 56749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public int getActionBarHideOffset() { 568fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas return mActionBarTop != null ? -((int) mActionBarTop.getTranslationY()) : 0; 56949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 57049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 57149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setActionBarHideOffset(int offset) { 57249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes haltActionBarHideOffsetAnimations(); 57349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int topHeight = mActionBarTop.getHeight(); 57449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes offset = Math.max(0, Math.min(offset, topHeight)); 575fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas mActionBarTop.setTranslationY(-offset); 57649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 57749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 5782c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas void haltActionBarHideOffsetAnimations() { 57949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes removeCallbacks(mRemoveActionBarHideOffset); 58049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes removeCallbacks(mAddActionBarHideOffset); 58149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mCurrentActionBarTopAnimator != null) { 58249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mCurrentActionBarTopAnimator.cancel(); 58349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 58449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 58549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 58649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private void postRemoveActionBarHideOffset() { 58749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes haltActionBarHideOffsetAnimations(); 58849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes postDelayed(mRemoveActionBarHideOffset, ACTION_BAR_ANIMATE_DELAY); 58949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 59049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 59149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private void postAddActionBarHideOffset() { 59249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes haltActionBarHideOffsetAnimations(); 59349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes postDelayed(mAddActionBarHideOffset, ACTION_BAR_ANIMATE_DELAY); 59449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 59549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 59649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private void removeActionBarHideOffset() { 59749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes haltActionBarHideOffsetAnimations(); 59849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mRemoveActionBarHideOffset.run(); 59949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 60049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 60149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private void addActionBarHideOffset() { 60249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes haltActionBarHideOffsetAnimations(); 60349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mAddActionBarHideOffset.run(); 60449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 60549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 60649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private boolean shouldHideActionBarOnFling(float velocityX, float velocityY) { 60749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mFlingEstimator.fling(0, 0, 0, (int) velocityY, 0, 0, Integer.MIN_VALUE, Integer.MAX_VALUE); 60849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int finalY = mFlingEstimator.getFinalY(); 60949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return finalY > mActionBarTop.getHeight(); 61049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 61149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 61249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 613f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public void setWindowCallback(Window.Callback cb) { 61449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 61549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.setWindowCallback(cb); 61649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 61749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 61849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 61949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setWindowTitle(CharSequence title) { 62049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 62149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.setWindowTitle(title); 62249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 62349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 62449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 62549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public CharSequence getTitle() { 62649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 62749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mDecorToolbar.getTitle(); 62849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 62949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 63049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 63149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void initFeature(int windowFeature) { 63249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 63349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes switch (windowFeature) { 63449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes case Window.FEATURE_PROGRESS: 63549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.initProgress(); 63649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 63749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes case Window.FEATURE_INDETERMINATE_PROGRESS: 63849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.initIndeterminateProgress(); 63949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 640ee322d85233b857047ba629a2456adc0b0392b4bChris Banes case AppCompatDelegate.FEATURE_SUPPORT_ACTION_BAR_OVERLAY: 64149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setOverlayMode(true); 64249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 64349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 64449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 64549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 64649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 64749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setUiOptions(int uiOptions) { 64849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Split Action Bar not included. 64949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 65049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 65149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 65249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean hasIcon() { 65349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 65449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mDecorToolbar.hasIcon(); 65549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 65649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 65749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 65849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean hasLogo() { 65949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 66049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mDecorToolbar.hasLogo(); 66149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 66249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 66349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 66449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setIcon(int resId) { 66549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 66649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.setIcon(resId); 66749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 66849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 66949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 67049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setIcon(Drawable d) { 67149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 67249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.setIcon(d); 67349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 67449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 67549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 67649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setLogo(int resId) { 67749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 67849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.setLogo(resId); 67949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 68049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 68149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 68249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean canShowOverflowMenu() { 68349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 68449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mDecorToolbar.canShowOverflowMenu(); 68549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 68649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 68749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 68849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean isOverflowMenuShowing() { 68949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 69049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mDecorToolbar.isOverflowMenuShowing(); 69149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 69249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 69349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 69449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean isOverflowMenuShowPending() { 69549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 69649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mDecorToolbar.isOverflowMenuShowPending(); 69749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 69849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 69949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 70049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean showOverflowMenu() { 70149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 70249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mDecorToolbar.showOverflowMenu(); 70349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 70449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 70549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 70649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean hideOverflowMenu() { 70749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 70849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mDecorToolbar.hideOverflowMenu(); 70949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 71049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 71149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 71249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setMenuPrepared() { 71349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 71449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.setMenuPrepared(); 71549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 71649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 71749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 71849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setMenu(Menu menu, MenuPresenter.Callback cb) { 71949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 72049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.setMenu(menu, cb); 72149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 72249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 72349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 72449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void saveToolbarHierarchyState(SparseArray<Parcelable> toolbarStates) { 72549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 72649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.saveHierarchyState(toolbarStates); 72749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 72849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 72949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 73049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void restoreToolbarHierarchyState(SparseArray<Parcelable> toolbarStates) { 73149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 73249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.restoreHierarchyState(toolbarStates); 73349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 73449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 73549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 73649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void dismissPopups() { 73749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 73849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.dismissPopupMenus(); 73949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 74049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 74149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public static class LayoutParams extends MarginLayoutParams { 74249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public LayoutParams(Context c, AttributeSet attrs) { 74349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super(c, attrs); 74449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 74549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 74649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public LayoutParams(int width, int height) { 74749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super(width, height); 74849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 74949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 75049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public LayoutParams(ViewGroup.LayoutParams source) { 75149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super(source); 75249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 75349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 75449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public LayoutParams(ViewGroup.MarginLayoutParams source) { 75549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super(source); 75649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 75749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 75849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 75949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public interface ActionBarVisibilityCallback { 76049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes void onWindowVisibilityChanged(int visibility); 76149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes void showForSystem(); 76249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes void hideForSystem(); 76349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes void enableContentAnimations(boolean enable); 76449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes void onContentScrollStarted(); 76549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes void onContentScrollStopped(); 766bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 767bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell} 768