ActionBarOverlayLayout.java revision ee322d85233b857047ba629a2456adc0b0392b4b
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 17da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownpackage android.support.v7.internal.widget; 18bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 19bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.Context; 2049c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.content.res.Configuration; 21bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.res.TypedArray; 2249c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.graphics.Canvas; 23bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.graphics.Rect; 2449c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.graphics.drawable.Drawable; 2549c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.os.Build; 2649c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.os.Parcelable; 27fa4c72b658085b888c94688d6882e66eabc50e25Chris Banesimport android.support.v4.view.NestedScrollingParent; 28fa4c72b658085b888c94688d6882e66eabc50e25Chris Banesimport android.support.v4.view.NestedScrollingParentHelper; 2949c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.view.ViewCompat; 3049c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.view.ViewPropertyAnimatorCompat; 3149c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.view.ViewPropertyAnimatorListener; 3249c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.view.ViewPropertyAnimatorListenerAdapter; 3349c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.widget.ScrollerCompat; 34ee322d85233b857047ba629a2456adc0b0392b4bChris Banesimport android.support.v7.app.AppCompatDelegate; 35d900fe072335d488f883585e3f686ef955d1ccc9Chris Banesimport android.support.v7.appcompat.R; 3608358d12169435b51d800bb7076fc4a540eafb8cChris Banesimport android.support.v7.internal.VersionUtils; 3749c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.MenuPresenter; 3849c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.widget.Toolbar; 39bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.util.AttributeSet; 4049c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.util.SparseArray; 4149c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.Menu; 42bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.View; 4349c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.ViewGroup; 4449c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.Window; 45bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 46bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell/** 4720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Special layout for the containing of an overlay action bar (and its content) to correctly handle 4820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * fitting system windows when the content has request that its layout ignore them. 4989208232f3b5d1451408d787872504a190bc7ee0Chris Banes * 5089208232f3b5d1451408d787872504a190bc7ee0Chris Banes * @hide 51bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell */ 52fa4c72b658085b888c94688d6882e66eabc50e25Chris Banespublic class ActionBarOverlayLayout extends ViewGroup implements DecorContentParent, 53fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes NestedScrollingParent { 5449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private static final String TAG = "ActionBarOverlayLayout"; 5520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 5620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private int mActionBarHeight; 5749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes //private WindowDecorActionBar mActionBar; 5849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private int mWindowVisibility = View.VISIBLE; 5949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 6049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // The main UI elements that we handle the layout of. 6149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private ContentFrameLayout mContent; 6249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private ActionBarContainer mActionBarBottom; 6349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private ActionBarContainer mActionBarTop; 6449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 6549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Some interior UI elements. 6649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private DecorToolbar mDecorToolbar; 6749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 6849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Content overlay drawable - generally the action bar's shadow 6949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private Drawable mWindowContentOverlay; 7049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private boolean mIgnoreWindowContentOverlay; 7149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 7249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private boolean mOverlayMode; 7349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private boolean mHasNonEmbeddedTabs; 7449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private boolean mHideOnContentScroll; 7549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private boolean mAnimatingForFling; 7649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private int mHideOnContentScrollReference; 7749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private int mLastSystemUiVisibility; 7849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private final Rect mBaseContentInsets = new Rect(); 7949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private final Rect mLastBaseContentInsets = new Rect(); 8049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private final Rect mContentInsets = new Rect(); 8149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private final Rect mBaseInnerInsets = new Rect(); 8249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private final Rect mInnerInsets = new Rect(); 8349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private final Rect mLastInnerInsets = new Rect(); 8449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 8549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private ActionBarVisibilityCallback mActionBarVisibilityCallback; 8649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 8749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private final int ACTION_BAR_ANIMATE_DELAY = 600; // ms 8849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 8949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private ScrollerCompat mFlingEstimator; 9049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 9149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private ViewPropertyAnimatorCompat mCurrentActionBarTopAnimator; 9249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private ViewPropertyAnimatorCompat mCurrentActionBarBottomAnimator; 9349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 9449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private final ViewPropertyAnimatorListener mTopAnimatorListener 9549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes = new ViewPropertyAnimatorListenerAdapter() { 9649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 9749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void onAnimationEnd(View view) { 9849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mCurrentActionBarTopAnimator = null; 9949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mAnimatingForFling = false; 10049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 10149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 10249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 10349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void onAnimationCancel(View view) { 10449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mCurrentActionBarTopAnimator = null; 10549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mAnimatingForFling = false; 10649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 10749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes }; 10849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 10949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private final ViewPropertyAnimatorListener mBottomAnimatorListener = 11049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes new ViewPropertyAnimatorListenerAdapter() { 11149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 11249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void onAnimationEnd(View view) { 11349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mCurrentActionBarBottomAnimator = null; 11449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mAnimatingForFling = false; 11549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 11649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 11749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 11849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void onAnimationCancel(View view) { 11949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mCurrentActionBarBottomAnimator = null; 12049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mAnimatingForFling = false; 12149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 12249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes }; 12349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 12449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private final Runnable mRemoveActionBarHideOffset = new Runnable() { 12549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void run() { 12649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes haltActionBarHideOffsetAnimations(); 12749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mCurrentActionBarTopAnimator = ViewCompat.animate(mActionBarTop).translationY(0) 12849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes .setListener(mTopAnimatorListener); 12949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mActionBarBottom != null && mActionBarBottom.getVisibility() != GONE) { 13049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mCurrentActionBarBottomAnimator = ViewCompat.animate(mActionBarBottom).translationY(0) 13149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes .setListener(mBottomAnimatorListener); 13249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 13349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 13449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes }; 13549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 13649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private final Runnable mAddActionBarHideOffset = new Runnable() { 13749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void run() { 13849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes haltActionBarHideOffsetAnimations(); 13949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mCurrentActionBarTopAnimator = ViewCompat.animate(mActionBarTop) 14049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes .translationY(-mActionBarTop.getHeight()) 14149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes .setListener(mTopAnimatorListener); 14249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mActionBarBottom != null && mActionBarBottom.getVisibility() != GONE) { 14349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mCurrentActionBarBottomAnimator = ViewCompat.animate(mActionBarBottom) 14449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes .translationY(mActionBarBottom.getHeight()) 14549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes .setListener(mBottomAnimatorListener); 14649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 14749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 14849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes }; 14949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 15049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes static final int[] ATTRS = new int [] { 15149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes R.attr.actionBarSize, 15249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes android.R.attr.windowContentOverlay 15320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns }; 15420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 155fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes private final NestedScrollingParentHelper mParentHelper; 156fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes 15720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public ActionBarOverlayLayout(Context context) { 158fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes this(context, null); 15920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 16020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 16120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public ActionBarOverlayLayout(Context context, AttributeSet attrs) { 16220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns super(context, attrs); 16320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns init(context); 164fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes 165fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes mParentHelper = new NestedScrollingParentHelper(this); 166bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 16720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 16820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private void init(Context context) { 16949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes TypedArray ta = getContext().getTheme().obtainStyledAttributes(ATTRS); 17020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mActionBarHeight = ta.getDimensionPixelSize(0, 0); 17149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mWindowContentOverlay = ta.getDrawable(1); 17249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setWillNotDraw(mWindowContentOverlay == null); 17320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ta.recycle(); 17449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 17549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mIgnoreWindowContentOverlay = context.getApplicationInfo().targetSdkVersion < 17649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes Build.VERSION_CODES.KITKAT; 17749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 17849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mFlingEstimator = ScrollerCompat.create(context); 17949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 18049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 18149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 18249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected void onDetachedFromWindow() { 18349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super.onDetachedFromWindow(); 18449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes haltActionBarHideOffsetAnimations(); 18549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 18649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 18749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setActionBarVisibilityCallback(ActionBarVisibilityCallback cb) { 18849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionBarVisibilityCallback = cb; 18949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (getWindowToken() != null) { 19049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // This is being initialized after being added to a window; 19149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // make sure to update all state now. 19249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionBarVisibilityCallback.onWindowVisibilityChanged(mWindowVisibility); 19349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mLastSystemUiVisibility != 0) { 19449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int newVis = mLastSystemUiVisibility; 19549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes onWindowSystemUiVisibilityChanged(newVis); 19649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ViewCompat.requestApplyInsets(this); 19749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 19849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 19949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 20049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 20149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setOverlayMode(boolean overlayMode) { 20249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mOverlayMode = overlayMode; 20349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 20449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /* 20549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Drawing the window content overlay was broken before K so starting to draw it 20649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * again unexpectedly will cause artifacts in some apps. They should fix it. 20749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 20849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mIgnoreWindowContentOverlay = overlayMode && 20949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes getContext().getApplicationInfo().targetSdkVersion < 21049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes Build.VERSION_CODES.KITKAT; 211bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 21220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 21349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean isInOverlayMode() { 21449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mOverlayMode; 21549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 21649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 21749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setHasNonEmbeddedTabs(boolean hasNonEmbeddedTabs) { 21849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mHasNonEmbeddedTabs = hasNonEmbeddedTabs; 21949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 22049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 22149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setShowingForActionMode(boolean showing) { 22249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // TODO: Add workaround for this 22349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// if (showing) { 22449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// // Here's a fun hack: if the status bar is currently being hidden, 22549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// // and the application has asked for stable content insets, then 22649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// // we will end up with the action mode action bar being shown 22749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// // without the status bar, but moved below where the status bar 22849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// // would be. Not nice. Trying to have this be positioned 22949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// // correctly is not easy (basically we need yet *another* content 23049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// // inset from the window manager to know where to put it), so 23149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// // instead we will just temporarily force the status bar to be shown. 23249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// if ((getWindowSystemUiVisibility() & (SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 23349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// | SYSTEM_UI_FLAG_LAYOUT_STABLE)) 23449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// == (SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | SYSTEM_UI_FLAG_LAYOUT_STABLE)) { 23549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// setDisabledSystemUiVisibility(SYSTEM_UI_FLAG_FULLSCREEN); 23649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// } 23749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// } else { 23849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// setDisabledSystemUiVisibility(0); 23949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes// } 24049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 24149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 24249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected void onConfigurationChanged(Configuration newConfig) { 24349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (Build.VERSION.SDK_INT >= 8) { 24449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super.onConfigurationChanged(newConfig); 24549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 24649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes init(getContext()); 24749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ViewCompat.requestApplyInsets(this); 24849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 24949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 25049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void onWindowSystemUiVisibilityChanged(int visible) { 25149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (Build.VERSION.SDK_INT >= 16) { 25249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super.onWindowSystemUiVisibilityChanged(visible); 25349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 25449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 25549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int diff = mLastSystemUiVisibility ^ visible; 25649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mLastSystemUiVisibility = visible; 25749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final boolean barVisible = (visible & SYSTEM_UI_FLAG_FULLSCREEN) == 0; 25849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final boolean stable = (visible & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0; 25949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mActionBarVisibilityCallback != null) { 26049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // We want the bar to be visible if it is not being hidden, 26149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // or the app has not turned on a stable UI mode (meaning they 26249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // are performing explicit layout around the action bar). 26349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionBarVisibilityCallback.enableContentAnimations(!stable); 26449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (barVisible || !stable) mActionBarVisibilityCallback.showForSystem(); 26549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes else mActionBarVisibilityCallback.hideForSystem(); 26649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 26749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if ((diff & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0) { 26849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mActionBarVisibilityCallback != null) { 26949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ViewCompat.requestApplyInsets(this); 27049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 27149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 27249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 27349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 27449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 27549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected void onWindowVisibilityChanged(int visibility) { 27649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super.onWindowVisibilityChanged(visibility); 27749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mWindowVisibility = visibility; 27849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mActionBarVisibilityCallback != null) { 27949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionBarVisibilityCallback.onWindowVisibilityChanged(visibility); 28049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 281bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 28220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 28320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private boolean applyInsets(View view, Rect insets, boolean left, boolean top, 28420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns boolean bottom, boolean right) { 28520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns boolean changed = false; 28649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes LayoutParams lp = (LayoutParams)view.getLayoutParams(); 28720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (left && lp.leftMargin != insets.left) { 28820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns changed = true; 28920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns lp.leftMargin = insets.left; 29020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 29120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (top && lp.topMargin != insets.top) { 29220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns changed = true; 29320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns lp.topMargin = insets.top; 29420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 29520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (right && lp.rightMargin != insets.right) { 29620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns changed = true; 29720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns lp.rightMargin = insets.right; 29820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 29920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (bottom && lp.bottomMargin != insets.bottom) { 30020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns changed = true; 30120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns lp.bottomMargin = insets.bottom; 30220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 30320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return changed; 304bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 30520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 30626f676060f6b45921a809c696acceac9c031c85bChris Banes @Override 30726f676060f6b45921a809c696acceac9c031c85bChris Banes protected boolean fitSystemWindows(Rect insets) { 30826f676060f6b45921a809c696acceac9c031c85bChris Banes pullChildren(); 30926f676060f6b45921a809c696acceac9c031c85bChris Banes 31026f676060f6b45921a809c696acceac9c031c85bChris Banes final int vis = ViewCompat.getWindowSystemUiVisibility(this); 31126f676060f6b45921a809c696acceac9c031c85bChris Banes final boolean stable = (vis & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0; 31226f676060f6b45921a809c696acceac9c031c85bChris Banes final Rect systemInsets = insets; 31326f676060f6b45921a809c696acceac9c031c85bChris Banes 314ade8ff8ba125b7d370de9ef5033ccbe89b2a30ccChris Banes // The top and bottom action bars are always within the content area. 315ade8ff8ba125b7d370de9ef5033ccbe89b2a30ccChris Banes boolean changed = applyInsets(mActionBarTop, systemInsets, true, true, false, true); 316ade8ff8ba125b7d370de9ef5033ccbe89b2a30ccChris Banes if (mActionBarBottom != null) { 317ade8ff8ba125b7d370de9ef5033ccbe89b2a30ccChris Banes changed |= applyInsets(mActionBarBottom, systemInsets, true, false, true, true); 318ade8ff8ba125b7d370de9ef5033ccbe89b2a30ccChris Banes } 31926f676060f6b45921a809c696acceac9c031c85bChris Banes 32026f676060f6b45921a809c696acceac9c031c85bChris Banes mBaseInnerInsets.set(systemInsets); 3211f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes ViewUtils.computeFitSystemWindows(this, mBaseInnerInsets, mBaseContentInsets); 32226f676060f6b45921a809c696acceac9c031c85bChris Banes if (!mLastBaseContentInsets.equals(mBaseContentInsets)) { 32326f676060f6b45921a809c696acceac9c031c85bChris Banes changed = true; 32426f676060f6b45921a809c696acceac9c031c85bChris Banes mLastBaseContentInsets.set(mBaseContentInsets); 32526f676060f6b45921a809c696acceac9c031c85bChris Banes } 32626f676060f6b45921a809c696acceac9c031c85bChris Banes 32726f676060f6b45921a809c696acceac9c031c85bChris Banes if (changed) { 32826f676060f6b45921a809c696acceac9c031c85bChris Banes requestLayout(); 32926f676060f6b45921a809c696acceac9c031c85bChris Banes } 33026f676060f6b45921a809c696acceac9c031c85bChris Banes 33126f676060f6b45921a809c696acceac9c031c85bChris Banes // We don't do any more at this point. To correctly compute the content/inner 33226f676060f6b45921a809c696acceac9c031c85bChris Banes // insets in all cases, we need to know the measured size of the various action 33326f676060f6b45921a809c696acceac9c031c85bChris Banes // bar elements. fitSystemWindows() happens before the measure pass, so we can't 33426f676060f6b45921a809c696acceac9c031c85bChris Banes // do that here. Instead we will take this up in onMeasure(). 33526f676060f6b45921a809c696acceac9c031c85bChris Banes return true; 33626f676060f6b45921a809c696acceac9c031c85bChris Banes } 33749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 33849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 33949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected LayoutParams generateDefaultLayoutParams() { 34049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 34149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 34249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 34349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 34449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public LayoutParams generateLayoutParams(AttributeSet attrs) { 34549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return new LayoutParams(getContext(), attrs); 34649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 34749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 34849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 34949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { 35049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return new LayoutParams(p); 35149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 35249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 35349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 35449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { 35549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return p instanceof LayoutParams; 35649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 35749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 35849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 35949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 36049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 36149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 36249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int maxHeight = 0; 36349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int maxWidth = 0; 36449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int childState = 0; 36549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 36649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int topInset = 0; 36749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int bottomInset = 0; 36849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 36949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes measureChildWithMargins(mActionBarTop, widthMeasureSpec, 0, heightMeasureSpec, 0); 37049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes LayoutParams lp = (LayoutParams) mActionBarTop.getLayoutParams(); 37149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxWidth = Math.max(maxWidth, 37249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionBarTop.getMeasuredWidth() + lp.leftMargin + lp.rightMargin); 37349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxHeight = Math.max(maxHeight, 37449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionBarTop.getMeasuredHeight() + lp.topMargin + lp.bottomMargin); 37549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childState = ViewUtils.combineMeasuredStates(childState, 37649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ViewCompat.getMeasuredState(mActionBarTop)); 37749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 37849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // xlarge screen layout doesn't have bottom action bar. 37949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mActionBarBottom != null) { 38049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes measureChildWithMargins(mActionBarBottom, widthMeasureSpec, 0, heightMeasureSpec, 0); 38149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes lp = (LayoutParams) mActionBarBottom.getLayoutParams(); 38249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxWidth = Math.max(maxWidth, 38349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionBarBottom.getMeasuredWidth() + lp.leftMargin + lp.rightMargin); 38449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxHeight = Math.max(maxHeight, 38549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionBarBottom.getMeasuredHeight() + lp.topMargin + lp.bottomMargin); 38649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childState = ViewUtils.combineMeasuredStates(childState, 38749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ViewCompat.getMeasuredState(mActionBarBottom)); 38849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 38949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 39049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int vis = ViewCompat.getWindowSystemUiVisibility(this); 39149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final boolean stable = (vis & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0; 39249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 39349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (stable) { 39449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // This is the standard space needed for the action bar. For stable measurement, 39549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // we can't depend on the size currently reported by it -- this must remain constant. 39649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes topInset = mActionBarHeight; 39749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mHasNonEmbeddedTabs) { 39849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final View tabs = mActionBarTop.getTabContainer(); 39949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (tabs != null) { 40049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // If tabs are not embedded, increase space on top to account for them. 40149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes topInset += mActionBarHeight; 40249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 40349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 40449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else if (mActionBarTop.getVisibility() != GONE) { 40549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // This is the space needed on top of the window for all of the action bar 40649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // and tabs. 40749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes topInset = mActionBarTop.getMeasuredHeight(); 40849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 40949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 41049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mDecorToolbar.isSplit()) { 41149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // If action bar is split, adjust bottom insets for it. 41249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mActionBarBottom != null) { 41349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (stable) { 41449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes bottomInset = mActionBarHeight; 41549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 41649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes bottomInset = mActionBarBottom.getMeasuredHeight(); 41749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 41849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 41949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 42049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 42149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // If the window has not requested system UI layout flags, we need to 42249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // make sure its content is not being covered by system UI... though it 42349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // will still be covered by the action bar if they have requested it to 42449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // overlay. 42549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mContentInsets.set(mBaseContentInsets); 42649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mInnerInsets.set(mBaseInnerInsets); 42749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (!mOverlayMode && !stable) { 42849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mContentInsets.top += topInset; 42949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mContentInsets.bottom += bottomInset; 43049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 43149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mInnerInsets.top += topInset; 43249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mInnerInsets.bottom += bottomInset; 43349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 43449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes applyInsets(mContent, mContentInsets, true, true, true, true); 43549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 43649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (!mLastInnerInsets.equals(mInnerInsets)) { 43749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // If the inner insets have changed, we need to dispatch this down to 43849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // the app's fitSystemWindows(). We do this before measuring the content 43949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // view to keep the same semantics as the normal fitSystemWindows() call. 44049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mLastInnerInsets.set(mInnerInsets); 44149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 44249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mContent.dispatchFitSystemWindows(mInnerInsets); 44349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 44449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 44549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes measureChildWithMargins(mContent, widthMeasureSpec, 0, heightMeasureSpec, 0); 44649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes lp = (LayoutParams) mContent.getLayoutParams(); 44749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxWidth = Math.max(maxWidth, 44849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mContent.getMeasuredWidth() + lp.leftMargin + lp.rightMargin); 44949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxHeight = Math.max(maxHeight, 45049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mContent.getMeasuredHeight() + lp.topMargin + lp.bottomMargin); 45149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childState = ViewUtils.combineMeasuredStates(childState, 45249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ViewCompat.getMeasuredState(mContent)); 45349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 45449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Account for padding too 45549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxWidth += getPaddingLeft() + getPaddingRight(); 45649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxHeight += getPaddingTop() + getPaddingBottom(); 45749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 45849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Check against our minimum height and width 45949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight()); 46049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth()); 46149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 46249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setMeasuredDimension( 46349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ViewCompat.resolveSizeAndState(maxWidth, widthMeasureSpec, childState), 46449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ViewCompat.resolveSizeAndState(maxHeight, heightMeasureSpec, 46549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childState << MEASURED_HEIGHT_STATE_SHIFT)); 46649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 46749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 46849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 46949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 47049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int count = getChildCount(); 47149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 47249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int parentLeft = getPaddingLeft(); 47349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int parentRight = right - left - getPaddingRight(); 47449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 47549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int parentTop = getPaddingTop(); 47649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int parentBottom = bottom - top - getPaddingBottom(); 47749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 47849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes for (int i = 0; i < count; i++) { 47949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final View child = getChildAt(i); 48049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child.getVisibility() != GONE) { 48149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 48249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 48349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int width = child.getMeasuredWidth(); 48449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int height = child.getMeasuredHeight(); 48549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 48649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int childLeft = parentLeft + lp.leftMargin; 48749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int childTop; 48849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child == mActionBarBottom) { 48949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childTop = parentBottom - height - lp.bottomMargin; 49049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 49149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childTop = parentTop + lp.topMargin; 49249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 49349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 49449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes child.layout(childLeft, childTop, childLeft + width, childTop + height); 49549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 49649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 49749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 49849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 49949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 50049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void draw(Canvas c) { 50149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super.draw(c); 50249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mWindowContentOverlay != null && !mIgnoreWindowContentOverlay) { 50349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int top = mActionBarTop.getVisibility() == VISIBLE ? 50449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes (int) (mActionBarTop.getBottom() + ViewCompat.getTranslationY(mActionBarTop) + 0.5f) 50549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes : 0; 50649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mWindowContentOverlay.setBounds(0, top, getWidth(), 50749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes top + mWindowContentOverlay.getIntrinsicHeight()); 50849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mWindowContentOverlay.draw(c); 50949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 51049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 51149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 51249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 51349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean shouldDelayChildPressedState() { 51449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return false; 51549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 51649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 51749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 51849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean onStartNestedScroll(View child, View target, int axes) { 51949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if ((axes & SCROLL_AXIS_VERTICAL) == 0 || mActionBarTop.getVisibility() != VISIBLE) { 52049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return false; 52149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 52249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mHideOnContentScroll; 52349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 52449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 52549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 52649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void onNestedScrollAccepted(View child, View target, int axes) { 527fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes mParentHelper.onNestedScrollAccepted(child, target, axes); 52849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mHideOnContentScrollReference = getActionBarHideOffset(); 52949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes haltActionBarHideOffsetAnimations(); 53049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mActionBarVisibilityCallback != null) { 53149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionBarVisibilityCallback.onContentScrollStarted(); 53249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 53349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 53449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 53549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 53649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void onNestedScroll(View target, int dxConsumed, int dyConsumed, 53749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int dxUnconsumed, int dyUnconsumed) { 53849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mHideOnContentScrollReference += dyConsumed; 53949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setActionBarHideOffset(mHideOnContentScrollReference); 54049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 54149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 54249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 54349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void onStopNestedScroll(View target) { 54449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mHideOnContentScroll && !mAnimatingForFling) { 54549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mHideOnContentScrollReference <= mActionBarTop.getHeight()) { 54649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes postRemoveActionBarHideOffset(); 54749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 54849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes postAddActionBarHideOffset(); 54949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 55049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 55149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mActionBarVisibilityCallback != null) { 55249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionBarVisibilityCallback.onContentScrollStopped(); 55349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 55449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 55549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 55649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 55749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) { 55849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (!mHideOnContentScroll || !consumed) { 55949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return false; 56049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 56149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (shouldHideActionBarOnFling(velocityX, velocityY)) { 56249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes addActionBarHideOffset(); 56349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 56449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes removeActionBarHideOffset(); 56549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 56649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mAnimatingForFling = true; 56749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return true; 56849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 56949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 570fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes @Override 571fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) { 572fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes // no-op 573fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes } 574fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes 575fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes @Override 576fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes public boolean onNestedPreFling(View target, float velocityX, float velocityY) { 577fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes return false; 578fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes } 579fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes 580fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes @Override 581fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes public int getNestedScrollAxes() { 582fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes return mParentHelper.getNestedScrollAxes(); 583fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes } 584fa4c72b658085b888c94688d6882e66eabc50e25Chris Banes 58520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns void pullChildren() { 58620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mContent == null) { 58749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mContent = (ContentFrameLayout) findViewById(R.id.action_bar_activity_content); 58849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionBarTop = (ActionBarContainer) findViewById(R.id.action_bar_container); 58949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar = getDecorToolbar(findViewById(R.id.action_bar)); 59049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionBarBottom = (ActionBarContainer) findViewById(R.id.split_action_bar); 59149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 59249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 59349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 59449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private DecorToolbar getDecorToolbar(View view) { 59549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (view instanceof DecorToolbar) { 59649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return (DecorToolbar) view; 59749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else if (view instanceof Toolbar) { 59849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return ((Toolbar) view).getWrapper(); 59949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 60049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes throw new IllegalStateException("Can't make a decor toolbar out of " + 60149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes view.getClass().getSimpleName()); 60249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 60349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 60449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 60549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setHideOnContentScrollEnabled(boolean hideOnContentScroll) { 60649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (hideOnContentScroll != mHideOnContentScroll) { 60749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mHideOnContentScroll = hideOnContentScroll; 60849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (!hideOnContentScroll) { 60949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes haltActionBarHideOffsetAnimations(); 61049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setActionBarHideOffset(0); 61149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 61249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 61349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 61449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 61549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean isHideOnContentScrollEnabled() { 61649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mHideOnContentScroll; 61749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 61849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 61949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public int getActionBarHideOffset() { 62049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mActionBarTop != null ? -((int) ViewCompat.getTranslationY(mActionBarTop)) : 0; 62149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 62249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 62349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setActionBarHideOffset(int offset) { 62449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes haltActionBarHideOffsetAnimations(); 62549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int topHeight = mActionBarTop.getHeight(); 62649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes offset = Math.max(0, Math.min(offset, topHeight)); 62749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ViewCompat.setTranslationY(mActionBarTop, -offset); 62849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mActionBarBottom != null && mActionBarBottom.getVisibility() != GONE) { 62949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Match the hide offset proportionally for a split bar 63049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final float fOffset = (float) offset / topHeight; 63149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int bOffset = (int) (mActionBarBottom.getHeight() * fOffset); 63249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ViewCompat.setTranslationY(mActionBarBottom, bOffset); 63349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 63449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 63549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 63649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private void haltActionBarHideOffsetAnimations() { 63749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes removeCallbacks(mRemoveActionBarHideOffset); 63849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes removeCallbacks(mAddActionBarHideOffset); 63949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mCurrentActionBarTopAnimator != null) { 64049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mCurrentActionBarTopAnimator.cancel(); 64149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 64249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mCurrentActionBarBottomAnimator != null) { 64349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mCurrentActionBarBottomAnimator.cancel(); 64449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 64549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 64649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 64749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private void postRemoveActionBarHideOffset() { 64849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes haltActionBarHideOffsetAnimations(); 64949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes postDelayed(mRemoveActionBarHideOffset, ACTION_BAR_ANIMATE_DELAY); 65049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 65149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 65249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private void postAddActionBarHideOffset() { 65349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes haltActionBarHideOffsetAnimations(); 65449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes postDelayed(mAddActionBarHideOffset, ACTION_BAR_ANIMATE_DELAY); 65549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 65649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 65749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private void removeActionBarHideOffset() { 65849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes haltActionBarHideOffsetAnimations(); 65949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mRemoveActionBarHideOffset.run(); 66049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 66149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 66249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private void addActionBarHideOffset() { 66349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes haltActionBarHideOffsetAnimations(); 66449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mAddActionBarHideOffset.run(); 66549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 66649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 66749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private boolean shouldHideActionBarOnFling(float velocityX, float velocityY) { 66849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mFlingEstimator.fling(0, 0, 0, (int) velocityY, 0, 0, Integer.MIN_VALUE, Integer.MAX_VALUE); 66949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int finalY = mFlingEstimator.getFinalY(); 67049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return finalY > mActionBarTop.getHeight(); 67149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 67249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 67349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 674f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public void setWindowCallback(Window.Callback cb) { 67549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 67649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.setWindowCallback(cb); 67749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 67849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 67949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 68049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setWindowTitle(CharSequence title) { 68149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 68249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.setWindowTitle(title); 68349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 68449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 68549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 68649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public CharSequence getTitle() { 68749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 68849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mDecorToolbar.getTitle(); 68949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 69049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 69149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 69249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void initFeature(int windowFeature) { 69349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 69449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes switch (windowFeature) { 69549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes case Window.FEATURE_PROGRESS: 69649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.initProgress(); 69749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 69849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes case Window.FEATURE_INDETERMINATE_PROGRESS: 69949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.initIndeterminateProgress(); 70049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 701ee322d85233b857047ba629a2456adc0b0392b4bChris Banes case AppCompatDelegate.FEATURE_SUPPORT_ACTION_BAR_OVERLAY: 70249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setOverlayMode(true); 70349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 70449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 70549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 70649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 70749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 70849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setUiOptions(int uiOptions) { 70949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Split Action Bar not included. 71049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 71149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 71249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 71349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean hasIcon() { 71449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 71549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mDecorToolbar.hasIcon(); 71649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 71749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 71849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 71949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean hasLogo() { 72049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 72149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mDecorToolbar.hasLogo(); 72249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 72349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 72449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 72549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setIcon(int resId) { 72649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 72749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.setIcon(resId); 72849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 72949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 73049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 73149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setIcon(Drawable d) { 73249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 73349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.setIcon(d); 73449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 73549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 73649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 73749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setLogo(int resId) { 73849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 73949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.setLogo(resId); 74049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 74149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 74249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 74349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean canShowOverflowMenu() { 74449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 74549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mDecorToolbar.canShowOverflowMenu(); 74649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 74749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 74849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 74949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean isOverflowMenuShowing() { 75049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 75149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mDecorToolbar.isOverflowMenuShowing(); 75249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 75349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 75449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 75549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean isOverflowMenuShowPending() { 75649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 75749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mDecorToolbar.isOverflowMenuShowPending(); 75849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 75949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 76049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 76149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean showOverflowMenu() { 76249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 76349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mDecorToolbar.showOverflowMenu(); 76449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 76549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 76649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 76749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean hideOverflowMenu() { 76849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 76949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mDecorToolbar.hideOverflowMenu(); 77049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 77149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 77249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 77349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setMenuPrepared() { 77449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 77549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.setMenuPrepared(); 77649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 77749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 77849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 77949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setMenu(Menu menu, MenuPresenter.Callback cb) { 78049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 78149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.setMenu(menu, cb); 78249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 78349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 78449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 78549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void saveToolbarHierarchyState(SparseArray<Parcelable> toolbarStates) { 78649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 78749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.saveHierarchyState(toolbarStates); 78849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 78949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 79049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 79149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void restoreToolbarHierarchyState(SparseArray<Parcelable> toolbarStates) { 79249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 79349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.restoreHierarchyState(toolbarStates); 79449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 79549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 79649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 79749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void dismissPopups() { 79849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes pullChildren(); 79949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorToolbar.dismissPopupMenus(); 80049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 80149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 80249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public static class LayoutParams extends MarginLayoutParams { 80349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public LayoutParams(Context c, AttributeSet attrs) { 80449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super(c, attrs); 80549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 80649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 80749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public LayoutParams(int width, int height) { 80849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super(width, height); 80949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 81049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 81149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public LayoutParams(ViewGroup.LayoutParams source) { 81249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super(source); 81349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 81449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 81549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public LayoutParams(ViewGroup.MarginLayoutParams source) { 81649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super(source); 81749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 81849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 81949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 82049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public interface ActionBarVisibilityCallback { 82149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes void onWindowVisibilityChanged(int visibility); 82249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes void showForSystem(); 82349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes void hideForSystem(); 82449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes void enableContentAnimations(boolean enable); 82549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes void onContentScrollStarted(); 82649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes void onContentScrollStopped(); 827bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 828bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell} 829