13a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn/* 23a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * Copyright (C) 2012 The Android Open Source Project 33a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * 43a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 53a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * you may not use this file except in compliance with the License. 63a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * You may obtain a copy of the License at 73a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * 83a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 93a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * 103a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 113a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 123a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * See the License for the specific language governing permissions and 143a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * limitations under the License. 153a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn */ 163a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn 173a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackbornpackage com.android.internal.widget; 183a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn 191dc5f92716189da02aa62f508adb6099061668b5Dianne Hackbornimport android.view.ViewGroup; 203a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackbornimport com.android.internal.app.ActionBarImpl; 213a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn 223a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackbornimport android.content.Context; 233a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackbornimport android.content.res.TypedArray; 243a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackbornimport android.graphics.Rect; 253a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackbornimport android.util.AttributeSet; 263a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackbornimport android.view.View; 273a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn 283a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn/** 293a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * Special layout for the containing of an overlay action bar (and its 303a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * content) to correctly handle fitting system windows when the content 313a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * has request that its layout ignore them. 323a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn */ 331dc5f92716189da02aa62f508adb6099061668b5Dianne Hackbornpublic class ActionBarOverlayLayout extends ViewGroup { 343a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn private int mActionBarHeight; 353a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn private ActionBarImpl mActionBar; 363a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn private int mWindowVisibility = View.VISIBLE; 371dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 381dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn // The main UI elements that we handle the layout of. 393a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn private View mContent; 403a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn private View mActionBarTop; 411dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn private View mActionBarBottom; 421dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 431dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn // Some interior UI elements. 443a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn private ActionBarContainer mContainerView; 453a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn private ActionBarView mActionView; 461dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 47df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn private boolean mOverlayMode; 483a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn private int mLastSystemUiVisibility; 491dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn private final Rect mBaseContentInsets = new Rect(); 501dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn private final Rect mLastBaseContentInsets = new Rect(); 511dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn private final Rect mContentInsets = new Rect(); 521dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn private final Rect mBaseInnerInsets = new Rect(); 531dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn private final Rect mInnerInsets = new Rect(); 541dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn private final Rect mLastInnerInsets = new Rect(); 553a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn 563a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn static final int[] mActionBarSizeAttr = new int [] { 573a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn com.android.internal.R.attr.actionBarSize 583a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn }; 593a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn 603a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn public ActionBarOverlayLayout(Context context) { 613a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn super(context); 623a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn init(context); 633a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 643a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn 653a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn public ActionBarOverlayLayout(Context context, AttributeSet attrs) { 663a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn super(context, attrs); 673a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn init(context); 683a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 693a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn 703a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn private void init(Context context) { 713a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn TypedArray ta = getContext().getTheme().obtainStyledAttributes(mActionBarSizeAttr); 723a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn mActionBarHeight = ta.getDimensionPixelSize(0, 0); 733a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn ta.recycle(); 743a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 753a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn 76df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn public void setActionBar(ActionBarImpl impl, boolean overlayMode) { 773a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn mActionBar = impl; 78df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn mOverlayMode = overlayMode; 793a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn if (getWindowToken() != null) { 803a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn // This is being initialized after being added to a window; 813a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn // make sure to update all state now. 823a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn mActionBar.setWindowVisibility(mWindowVisibility); 833a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn if (mLastSystemUiVisibility != 0) { 843a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn int newVis = mLastSystemUiVisibility; 853a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn onWindowSystemUiVisibilityChanged(newVis); 863a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn requestFitSystemWindows(); 873a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 883a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 893a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 903a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn 91139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn public void setShowingForActionMode(boolean showing) { 92139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn if (showing) { 93139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn // Here's a fun hack: if the status bar is currently being hidden, 94139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn // and the application has asked for stable content insets, then 95139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn // we will end up with the action mode action bar being shown 96139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn // without the status bar, but moved below where the status bar 97139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn // would be. Not nice. Trying to have this be positioned 98139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn // correctly is not easy (basically we need yet *another* content 99139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn // inset from the window manager to know where to put it), so 100139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn // instead we will just temporarily force the status bar to be shown. 101139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn if ((getWindowSystemUiVisibility() & (SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 102139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn | SYSTEM_UI_FLAG_LAYOUT_STABLE)) 103139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn == (SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | SYSTEM_UI_FLAG_LAYOUT_STABLE)) { 104139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn setDisabledSystemUiVisibility(SYSTEM_UI_FLAG_FULLSCREEN); 105139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn } 106139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn } else { 107139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn setDisabledSystemUiVisibility(0); 108139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn } 109139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn } 110139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn 1113a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn @Override 1123a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn public void onWindowSystemUiVisibilityChanged(int visible) { 1133a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn super.onWindowSystemUiVisibilityChanged(visible); 1143a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn pullChildren(); 1153a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn final int diff = mLastSystemUiVisibility ^ visible; 1163a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn mLastSystemUiVisibility = visible; 1173a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn final boolean barVisible = (visible&SYSTEM_UI_FLAG_FULLSCREEN) == 0; 118139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn final boolean wasVisible = mActionBar != null ? mActionBar.isSystemShowing() : true; 119df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn final boolean stable = (visible&SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0; 120139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn if (mActionBar != null) { 121df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn // We want the bar to be visible if it is not being hidden, 122df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn // or the app has not turned on a stable UI mode (meaning they 123df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn // are performing explicit layout around the action bar). 124df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn mActionBar.enableContentAnimations(!stable); 125df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn if (barVisible || !stable) mActionBar.showForSystem(); 126139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn else mActionBar.hideForSystem(); 127139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn } 128139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn if ((diff&SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0) { 1293a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn if (mActionBar != null) { 1303a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn requestFitSystemWindows(); 1313a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 1323a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 1333a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 1343a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn 1353a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn @Override 1363a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn protected void onWindowVisibilityChanged(int visibility) { 1373a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn super.onWindowVisibilityChanged(visibility); 1383a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn mWindowVisibility = visibility; 1393a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn if (mActionBar != null) { 1403a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn mActionBar.setWindowVisibility(visibility); 1413a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 1423a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 1433a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn 1443a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn private boolean applyInsets(View view, Rect insets, boolean left, boolean top, 1453a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn boolean bottom, boolean right) { 1463a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn boolean changed = false; 1471dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn LayoutParams lp = (LayoutParams)view.getLayoutParams(); 1483a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn if (left && lp.leftMargin != insets.left) { 1493a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn changed = true; 1503a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn lp.leftMargin = insets.left; 1513a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 1523a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn if (top && lp.topMargin != insets.top) { 1533a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn changed = true; 1543a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn lp.topMargin = insets.top; 1553a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 1563a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn if (right && lp.rightMargin != insets.right) { 1573a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn changed = true; 1583a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn lp.rightMargin = insets.right; 1593a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 1603a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn if (bottom && lp.bottomMargin != insets.bottom) { 1613a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn changed = true; 1623a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn lp.bottomMargin = insets.bottom; 1633a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 1643a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn return changed; 1653a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 1663a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn 1673a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn @Override 1683a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn protected boolean fitSystemWindows(Rect insets) { 1693a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn pullChildren(); 1703a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn 1713a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn final int vis = getWindowSystemUiVisibility(); 1723a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn final boolean stable = (vis & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0; 1733a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn 1743a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn // The top and bottom action bars are always within the content area. 1753a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn boolean changed = applyInsets(mActionBarTop, insets, true, true, false, true); 176474690caf8b3bece133b40914979ac2520036989Dianne Hackborn if (mActionBarBottom != null) { 177474690caf8b3bece133b40914979ac2520036989Dianne Hackborn changed |= applyInsets(mActionBarBottom, insets, true, false, true, true); 178474690caf8b3bece133b40914979ac2520036989Dianne Hackborn } 1791dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 1801dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn mBaseInnerInsets.set(insets); 1811dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn computeFitSystemWindows(mBaseInnerInsets, mBaseContentInsets); 1821dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn if (!mLastBaseContentInsets.equals(mBaseContentInsets)) { 1831dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn changed = true; 1841dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn mLastBaseContentInsets.set(mBaseContentInsets); 185fe2b7ccca4c5fdaa0d77968b897bd789f4c87c30Dianne Hackborn } 1863a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn 1871dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn if (changed) { 1881dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn requestLayout(); 1893a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 1901dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 1911dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn // We don't do any more at this point. To correctly compute the content/inner 1921dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn // insets in all cases, we need to know the measured size of the various action 1931dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn // bar elements. fitSystemWindows() happens before the measure pass, so we can't 1941dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn // do that here. Instead we will take this up in onMeasure(). 1951dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn return true; 1961dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn } 1971dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 1981dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn @Override 1991dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn protected LayoutParams generateDefaultLayoutParams() { 2001dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 2011dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn } 2021dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 2031dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn @Override 2041dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn public LayoutParams generateLayoutParams(AttributeSet attrs) { 2051dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn return new LayoutParams(getContext(), attrs); 2061dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn } 2071dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 2081dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn @Override 2097cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { 2107cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn return new LayoutParams(p); 2117cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn } 2127cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn 2137cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn @Override 2147cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { 2157cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn return p instanceof LayoutParams; 2167cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn } 2177cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn 2187cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn @Override 2191dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 220474690caf8b3bece133b40914979ac2520036989Dianne Hackborn pullChildren(); 221474690caf8b3bece133b40914979ac2520036989Dianne Hackborn 2221dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn int maxHeight = 0; 2231dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn int maxWidth = 0; 2241dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn int childState = 0; 2251dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 2261dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn int topInset = 0; 2271dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn int bottomInset = 0; 2281dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 2291dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn measureChildWithMargins(mActionBarTop, widthMeasureSpec, 0, heightMeasureSpec, 0); 2301dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn LayoutParams lp = (LayoutParams) mActionBarTop.getLayoutParams(); 2311dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn maxWidth = Math.max(maxWidth, 2321dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn mActionBarTop.getMeasuredWidth() + lp.leftMargin + lp.rightMargin); 2331dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn maxHeight = Math.max(maxHeight, 2341dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn mActionBarTop.getMeasuredHeight() + lp.topMargin + lp.bottomMargin); 2351dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn childState = combineMeasuredStates(childState, mActionBarTop.getMeasuredState()); 2361dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 237474690caf8b3bece133b40914979ac2520036989Dianne Hackborn // xlarge screen layout doesn't have bottom action bar. 238474690caf8b3bece133b40914979ac2520036989Dianne Hackborn if (mActionBarBottom != null) { 239474690caf8b3bece133b40914979ac2520036989Dianne Hackborn measureChildWithMargins(mActionBarBottom, widthMeasureSpec, 0, heightMeasureSpec, 0); 240474690caf8b3bece133b40914979ac2520036989Dianne Hackborn lp = (LayoutParams) mActionBarBottom.getLayoutParams(); 241474690caf8b3bece133b40914979ac2520036989Dianne Hackborn maxWidth = Math.max(maxWidth, 242474690caf8b3bece133b40914979ac2520036989Dianne Hackborn mActionBarBottom.getMeasuredWidth() + lp.leftMargin + lp.rightMargin); 243474690caf8b3bece133b40914979ac2520036989Dianne Hackborn maxHeight = Math.max(maxHeight, 244474690caf8b3bece133b40914979ac2520036989Dianne Hackborn mActionBarBottom.getMeasuredHeight() + lp.topMargin + lp.bottomMargin); 245474690caf8b3bece133b40914979ac2520036989Dianne Hackborn childState = combineMeasuredStates(childState, mActionBarBottom.getMeasuredState()); 246474690caf8b3bece133b40914979ac2520036989Dianne Hackborn } 2471dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 2481dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn final int vis = getWindowSystemUiVisibility(); 2491dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn final boolean stable = (vis & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0; 2501dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 2511dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn if (stable) { 2521dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn // This is the standard space needed for the action bar. For stable measurement, 2531dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn // we can't depend on the size currently reported by it -- this must remain constant. 2541dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn topInset = mActionBarHeight; 2551dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn if (mActionBar != null && mActionBar.hasNonEmbeddedTabs()) { 2561dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn View tabs = mContainerView.getTabContainer(); 2571dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn if (tabs != null) { 2581dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn // If tabs are not embedded, increase space on top to account for them. 2591dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn topInset += mActionBarHeight; 2601dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn } 2613a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 2621dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn } else if (mActionBarTop.getVisibility() == VISIBLE) { 2631dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn // This is the space needed on top of the window for all of the action bar 2641dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn // and tabs. 2651dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn topInset = mActionBarTop.getMeasuredHeight(); 2663a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 2673a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn 2683a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn if (mActionView.isSplitActionBar()) { 2691dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn // If action bar is split, adjust bottom insets for it. 270474690caf8b3bece133b40914979ac2520036989Dianne Hackborn if (mActionBarBottom != null) { 271474690caf8b3bece133b40914979ac2520036989Dianne Hackborn if (stable) { 272474690caf8b3bece133b40914979ac2520036989Dianne Hackborn bottomInset = mActionBarHeight; 273474690caf8b3bece133b40914979ac2520036989Dianne Hackborn } else { 274474690caf8b3bece133b40914979ac2520036989Dianne Hackborn bottomInset = mActionBarBottom.getMeasuredHeight(); 275474690caf8b3bece133b40914979ac2520036989Dianne Hackborn } 2763a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 2773a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 2783a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn 279df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn // If the window has not requested system UI layout flags, we need to 280df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn // make sure its content is not being covered by system UI... though it 2811dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn // will still be covered by the action bar if they have requested it to 282df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn // overlay. 2831dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn mContentInsets.set(mBaseContentInsets); 2841dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn mInnerInsets.set(mBaseInnerInsets); 285df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn if (!mOverlayMode && !stable) { 2861dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn mContentInsets.top += topInset; 2871dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn mContentInsets.bottom += bottomInset; 288df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn } else { 2891dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn mInnerInsets.top += topInset; 2901dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn mInnerInsets.bottom += bottomInset; 291df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn } 2921dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn applyInsets(mContent, mContentInsets, true, true, true, true); 293df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn 2941dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn if (!mLastInnerInsets.equals(mInnerInsets)) { 2951dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn // If the inner insets have changed, we need to dispatch this down to 2961dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn // the app's fitSystemWindows(). We do this before measuring the content 2971dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn // view to keep the same semantics as the normal fitSystemWindows() call. 2981dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn mLastInnerInsets.set(mInnerInsets); 2991dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn super.fitSystemWindows(mInnerInsets); 3003a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 3013a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn 3021dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn measureChildWithMargins(mContent, widthMeasureSpec, 0, heightMeasureSpec, 0); 3031dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn lp = (LayoutParams) mContent.getLayoutParams(); 3041dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn maxWidth = Math.max(maxWidth, 3051dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn mContent.getMeasuredWidth() + lp.leftMargin + lp.rightMargin); 3061dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn maxHeight = Math.max(maxHeight, 3071dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn mContent.getMeasuredHeight() + lp.topMargin + lp.bottomMargin); 3081dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn childState = combineMeasuredStates(childState, mContent.getMeasuredState()); 3091dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 3101dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn // Account for padding too 3111dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn maxWidth += getPaddingLeft() + getPaddingRight(); 3121dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn maxHeight += getPaddingTop() + getPaddingBottom(); 3131dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 3141dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn // Check against our minimum height and width 3151dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight()); 3161dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth()); 3171dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 3181dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState), 3191dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn resolveSizeAndState(maxHeight, heightMeasureSpec, 3201dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn childState << MEASURED_HEIGHT_STATE_SHIFT)); 3211dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn } 3221dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 3231dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn @Override 3241dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 3251dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn final int count = getChildCount(); 3261dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 3271dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn final int parentLeft = getPaddingLeft(); 3281dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn final int parentRight = right - left - getPaddingRight(); 3291dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 3301dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn final int parentTop = getPaddingTop(); 3311dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn final int parentBottom = bottom - top - getPaddingBottom(); 3321dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 3331dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn for (int i = 0; i < count; i++) { 3341dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn final View child = getChildAt(i); 3351dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn if (child.getVisibility() != GONE) { 3361dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 3371dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 3381dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn final int width = child.getMeasuredWidth(); 3391dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn final int height = child.getMeasuredHeight(); 3401dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 3411dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn int childLeft = parentLeft + lp.leftMargin; 3421dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn int childTop; 3431dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn if (child == mActionBarBottom) { 3441dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn childTop = parentBottom - height - lp.bottomMargin; 3451dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn } else { 3461dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn childTop = parentTop + lp.topMargin; 3471dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn } 3481dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 3491dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn child.layout(childLeft, childTop, childLeft + width, childTop + height); 3501dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn } 3511dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn } 3523a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 3533a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn 3547cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn @Override 3557cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn public boolean shouldDelayChildPressedState() { 3567cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn return false; 3577cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn } 3587cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn 3593a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn void pullChildren() { 3603a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn if (mContent == null) { 3613a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn mContent = findViewById(com.android.internal.R.id.content); 3623a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn mActionBarTop = findViewById(com.android.internal.R.id.top_action_bar); 3633a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn mContainerView = (ActionBarContainer)findViewById( 3643a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn com.android.internal.R.id.action_bar_container); 3653a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn mActionView = (ActionBarView) findViewById(com.android.internal.R.id.action_bar); 3663a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn mActionBarBottom = findViewById(com.android.internal.R.id.split_action_bar); 3673a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 3683a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn } 3691dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 3701dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 3711dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn public static class LayoutParams extends MarginLayoutParams { 3721dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn public LayoutParams(Context c, AttributeSet attrs) { 3731dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn super(c, attrs); 3741dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn } 3751dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 3761dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn public LayoutParams(int width, int height) { 3771dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn super(width, height); 3781dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn } 3791dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 3801dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn public LayoutParams(ViewGroup.LayoutParams source) { 3811dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn super(source); 3821dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn } 3831dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn 3841dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn public LayoutParams(ViewGroup.MarginLayoutParams source) { 3851dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn super(source); 3861dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn } 3871dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn } 3883a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn} 389