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