package com.android.internal.app;
+import android.animation.ValueAnimator;
+import android.view.ViewParent;
import com.android.internal.view.ActionBarPolicy;
import com.android.internal.view.menu.MenuBuilder;
import com.android.internal.view.menu.MenuPopupHelper;
private ActionBarOverlayLayout mOverlayLayout;
private ActionBarContainer mContainerView;
- private ViewGroup mTopVisibilityView;
private ActionBarView mActionView;
private ActionBarContextView mContextView;
private ActionBarContainer mSplitView;
public void onAnimationEnd(Animator animation) {
if (mContentAnimations && mContentView != null) {
mContentView.setTranslationY(0);
- mTopVisibilityView.setTranslationY(0);
+ mContainerView.setTranslationY(0);
}
if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) {
mSplitView.setVisibility(View.GONE);
}
- mTopVisibilityView.setVisibility(View.GONE);
+ mContainerView.setVisibility(View.GONE);
mContainerView.setTransitioning(false);
mCurrentShowAnim = null;
completeDeferredDestroyActionMode();
@Override
public void onAnimationEnd(Animator animation) {
mCurrentShowAnim = null;
- mTopVisibilityView.requestLayout();
+ mContainerView.requestLayout();
+ }
+ };
+
+ final ValueAnimator.AnimatorUpdateListener mUpdateListener =
+ new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ final ViewParent parent = mContainerView.getParent();
+ ((View) parent).invalidate();
}
};
Window window = activity.getWindow();
View decor = window.getDecorView();
boolean overlayMode = mActivity.getWindow().hasFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
- init(decor, overlayMode);
+ init(decor);
if (!overlayMode) {
mContentView = decor.findViewById(android.R.id.content);
}
public ActionBarImpl(Dialog dialog) {
mDialog = dialog;
- init(dialog.getWindow().getDecorView(), false);
+ init(dialog.getWindow().getDecorView());
}
- private void init(View decor, boolean overlayMode) {
+ private void init(View decor) {
mContext = decor.getContext();
mOverlayLayout = (ActionBarOverlayLayout) decor.findViewById(
com.android.internal.R.id.action_bar_overlay_layout);
if (mOverlayLayout != null) {
- mOverlayLayout.setActionBar(this, overlayMode);
+ mOverlayLayout.setActionBar(this);
}
mActionView = (ActionBarView) decor.findViewById(com.android.internal.R.id.action_bar);
mContextView = (ActionBarContextView) decor.findViewById(
com.android.internal.R.id.action_context_bar);
mContainerView = (ActionBarContainer) decor.findViewById(
com.android.internal.R.id.action_bar_container);
- mTopVisibilityView = (ViewGroup)decor.findViewById(
- com.android.internal.R.id.top_action_bar);
- if (mTopVisibilityView == null) {
- mTopVisibilityView = mContainerView;
- }
mSplitView = (ActionBarContainer) decor.findViewById(
com.android.internal.R.id.split_action_bar);
if (mCurrentShowAnim != null) {
mCurrentShowAnim.end();
}
- mTopVisibilityView.setVisibility(View.VISIBLE);
+ mContainerView.setVisibility(View.VISIBLE);
if (mCurWindowVisibility == View.VISIBLE && (mShowHideAnimationEnabled
|| fromSystem)) {
- mTopVisibilityView.setTranslationY(0); // because we're about to ask its window loc
- float startingY = -mTopVisibilityView.getHeight();
+ mContainerView.setTranslationY(0); // because we're about to ask its window loc
+ float startingY = -mContainerView.getHeight();
if (fromSystem) {
int topLeft[] = {0, 0};
- mTopVisibilityView.getLocationInWindow(topLeft);
+ mContainerView.getLocationInWindow(topLeft);
startingY -= topLeft[1];
}
- mTopVisibilityView.setTranslationY(startingY);
+ mContainerView.setTranslationY(startingY);
AnimatorSet anim = new AnimatorSet();
- AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mTopVisibilityView,
- "translationY", 0));
+ ObjectAnimator a = ObjectAnimator.ofFloat(mContainerView, View.TRANSLATION_Y, 0);
+ a.addUpdateListener(mUpdateListener);
+ AnimatorSet.Builder b = anim.play(a);
if (mContentAnimations && mContentView != null) {
- b.with(ObjectAnimator.ofFloat(mContentView, "translationY",
+ b.with(ObjectAnimator.ofFloat(mContentView, View.TRANSLATION_Y,
startingY, 0));
}
if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) {
mSplitView.setTranslationY(mSplitView.getHeight());
mSplitView.setVisibility(View.VISIBLE);
- b.with(ObjectAnimator.ofFloat(mSplitView, "translationY", 0));
+ b.with(ObjectAnimator.ofFloat(mSplitView, View.TRANSLATION_Y, 0));
}
anim.setInterpolator(AnimationUtils.loadInterpolator(mContext,
com.android.internal.R.interpolator.decelerate_cubic));
mCurrentShowAnim = anim;
anim.start();
} else {
- mTopVisibilityView.setAlpha(1);
- mTopVisibilityView.setTranslationY(0);
+ mContainerView.setAlpha(1);
+ mContainerView.setTranslationY(0);
if (mContentAnimations && mContentView != null) {
mContentView.setTranslationY(0);
}
if (mCurWindowVisibility == View.VISIBLE && (mShowHideAnimationEnabled
|| fromSystem)) {
- mTopVisibilityView.setAlpha(1);
+ mContainerView.setAlpha(1);
mContainerView.setTransitioning(true);
AnimatorSet anim = new AnimatorSet();
- float endingY = -mTopVisibilityView.getHeight();
+ float endingY = -mContainerView.getHeight();
if (fromSystem) {
int topLeft[] = {0, 0};
- mTopVisibilityView.getLocationInWindow(topLeft);
+ mContainerView.getLocationInWindow(topLeft);
endingY -= topLeft[1];
}
- AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mTopVisibilityView,
- "translationY", endingY));
+ ObjectAnimator a = ObjectAnimator.ofFloat(mContainerView, View.TRANSLATION_Y, endingY);
+ a.addUpdateListener(mUpdateListener);
+ AnimatorSet.Builder b = anim.play(a);
if (mContentAnimations && mContentView != null) {
- b.with(ObjectAnimator.ofFloat(mContentView, "translationY",
+ b.with(ObjectAnimator.ofFloat(mContentView, View.TRANSLATION_Y,
0, endingY));
}
if (mSplitView != null && mSplitView.getVisibility() == View.VISIBLE) {
mSplitView.setAlpha(1);
- b.with(ObjectAnimator.ofFloat(mSplitView, "translationY",
+ b.with(ObjectAnimator.ofFloat(mSplitView, View.TRANSLATION_Y,
mSplitView.getHeight()));
}
anim.setInterpolator(AnimationUtils.loadInterpolator(mContext,
package com.android.internal.widget;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.util.Log;
import android.view.ViewGroup;
import com.android.internal.app.ActionBarImpl;
* has request that its layout ignore them.
*/
public class ActionBarOverlayLayout extends ViewGroup {
+ private static final String TAG = "ActionBarOverlayLayout";
+
private int mActionBarHeight;
private ActionBarImpl mActionBar;
private int mWindowVisibility = View.VISIBLE;
// The main UI elements that we handle the layout of.
private View mContent;
- private View mActionBarTop;
private View mActionBarBottom;
+ private ActionBarContainer mActionBarTop;
// Some interior UI elements.
- private ActionBarContainer mContainerView;
- private ActionBarView mActionView;
+ private ActionBarView mActionBarView;
+
+ // Content overlay drawable - generally the action bar's shadow
+ private Drawable mWindowContentOverlay;
+ private boolean mIgnoreWindowContentOverlay;
private boolean mOverlayMode;
private int mLastSystemUiVisibility;
private final Rect mInnerInsets = new Rect();
private final Rect mLastInnerInsets = new Rect();
- static final int[] mActionBarSizeAttr = new int [] {
- com.android.internal.R.attr.actionBarSize
+ static final int[] ATTRS = new int [] {
+ com.android.internal.R.attr.actionBarSize,
+ com.android.internal.R.attr.windowContentOverlay
};
public ActionBarOverlayLayout(Context context) {
}
private void init(Context context) {
- TypedArray ta = getContext().getTheme().obtainStyledAttributes(mActionBarSizeAttr);
+ TypedArray ta = getContext().getTheme().obtainStyledAttributes(ATTRS);
mActionBarHeight = ta.getDimensionPixelSize(0, 0);
+ mWindowContentOverlay = ta.getDrawable(1);
+ setWillNotDraw(mWindowContentOverlay == null);
ta.recycle();
+
+ mIgnoreWindowContentOverlay = context.getApplicationInfo().targetSdkVersion <
+ Build.VERSION_CODES.KEY_LIME_PIE;
}
- public void setActionBar(ActionBarImpl impl, boolean overlayMode) {
+ public void setActionBar(ActionBarImpl impl) {
mActionBar = impl;
- mOverlayMode = overlayMode;
if (getWindowToken() != null) {
// This is being initialized after being added to a window;
// make sure to update all state now.
}
}
+ public void setOverlayMode(boolean overlayMode) {
+ mOverlayMode = overlayMode;
+
+ /*
+ * Drawing the window content overlay was broken before K so starting to draw it
+ * again unexpectedly will cause artifacts in some apps. They should fix it.
+ */
+ mIgnoreWindowContentOverlay = overlayMode &&
+ getContext().getApplicationInfo().targetSdkVersion <
+ Build.VERSION_CODES.KEY_LIME_PIE;
+ }
+
public void setShowingForActionMode(boolean showing) {
if (showing) {
// Here's a fun hack: if the status bar is currently being hidden,
// we can't depend on the size currently reported by it -- this must remain constant.
topInset = mActionBarHeight;
if (mActionBar != null && mActionBar.hasNonEmbeddedTabs()) {
- View tabs = mContainerView.getTabContainer();
+ View tabs = mActionBarTop.getTabContainer();
if (tabs != null) {
// If tabs are not embedded, increase space on top to account for them.
topInset += mActionBarHeight;
topInset = mActionBarTop.getMeasuredHeight();
}
- if (mActionView.isSplitActionBar()) {
+ if (mActionBarView.isSplitActionBar()) {
// If action bar is split, adjust bottom insets for it.
if (mActionBarBottom != null) {
if (stable) {
}
@Override
+ public void draw(Canvas c) {
+ super.draw(c);
+ if (mWindowContentOverlay != null && !mIgnoreWindowContentOverlay) {
+ final int top = mActionBarTop.getVisibility() == VISIBLE ?
+ (int) (mActionBarTop.getBottom() + mActionBarTop.getTranslationY() + 0.5f) : 0;
+ mWindowContentOverlay.setBounds(0, top, getWidth(),
+ top + mWindowContentOverlay.getIntrinsicHeight());
+ mWindowContentOverlay.draw(c);
+ }
+ }
+
+ @Override
public boolean shouldDelayChildPressedState() {
return false;
}
void pullChildren() {
if (mContent == null) {
mContent = findViewById(com.android.internal.R.id.content);
- mActionBarTop = findViewById(com.android.internal.R.id.top_action_bar);
- mContainerView = (ActionBarContainer)findViewById(
+ mActionBarTop = (ActionBarContainer)findViewById(
com.android.internal.R.id.action_bar_container);
- mActionView = (ActionBarView) findViewById(com.android.internal.R.id.action_bar);
+ mActionBarView = (ActionBarView) findViewById(com.android.internal.R.id.action_bar);
mActionBarBottom = findViewById(com.android.internal.R.id.split_action_bar);
}
}
<FrameLayout android:id="@android:id/content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
- <LinearLayout android:id="@+id/top_action_bar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <com.android.internal.widget.ActionBarContainer android:id="@+id/action_bar_container"
+ <com.android.internal.widget.ActionBarContainer
+ android:id="@+id/action_bar_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ style="?android:attr/actionBarStyle"
+ android:gravity="top">
+ <com.android.internal.widget.ActionBarView
+ android:id="@+id/action_bar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="?android:attr/actionBarStyle" />
+ <com.android.internal.widget.ActionBarContextView
+ android:id="@+id/action_context_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_alignParentTop="true"
- style="?android:attr/actionBarStyle"
- android:gravity="top">
- <com.android.internal.widget.ActionBarView
- android:id="@+id/action_bar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="?android:attr/actionBarStyle" />
- <com.android.internal.widget.ActionBarContextView
- android:id="@+id/action_context_bar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:visibility="gone"
- style="?android:attr/actionModeStyle" />
- </com.android.internal.widget.ActionBarContainer>
- <ImageView android:src="?android:attr/windowContentOverlay"
- android:scaleType="fitXY"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
- </LinearLayout>
+ android:visibility="gone"
+ style="?android:attr/actionModeStyle" />
+ </com.android.internal.widget.ActionBarContainer>
</com.android.internal.widget.ActionBarOverlayLayout>
android:layout_height="match_parent"
android:splitMotionEvents="false">
<FrameLayout android:id="@android:id/content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+ <com.android.internal.widget.ActionBarContainer
+ android:id="@+id/action_bar_container"
android:layout_width="match_parent"
- android:layout_height="match_parent" />
- <LinearLayout android:id="@+id/top_action_bar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <com.android.internal.widget.ActionBarContainer android:id="@+id/action_bar_container"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ style="?android:attr/actionBarStyle"
+ android:gravity="top">
+ <com.android.internal.widget.ActionBarView
+ android:id="@+id/action_bar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="?android:attr/actionBarStyle" />
+ <com.android.internal.widget.ActionBarContextView
+ android:id="@+id/action_context_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_alignParentTop="true"
- style="?android:attr/actionBarStyle"
- android:gravity="top">
- <com.android.internal.widget.ActionBarView
- android:id="@+id/action_bar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="?android:attr/actionBarStyle" />
- <com.android.internal.widget.ActionBarContextView
- android:id="@+id/action_context_bar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:visibility="gone"
- style="?android:attr/actionModeStyle" />
- </com.android.internal.widget.ActionBarContainer>
- <ImageView android:src="?android:attr/windowContentOverlay"
- android:scaleType="fitXY"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
- </LinearLayout>
+ android:visibility="gone"
+ style="?android:attr/actionModeStyle" />
+ </com.android.internal.widget.ActionBarContainer>
<com.android.internal.widget.ActionBarContainer android:id="@+id/split_action_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
<java-symbol type="id" name="to_common" />
<java-symbol type="id" name="to_org" />
<java-symbol type="id" name="to_org_unit" />
- <java-symbol type="id" name="top_action_bar" />
<java-symbol type="id" name="topPanel" />
<java-symbol type="id" name="up" />
<java-symbol type="id" name="value" />
mActionBar.initIndeterminateProgress();
}
+ final ActionBarOverlayLayout abol = (ActionBarOverlayLayout) findViewById(
+ com.android.internal.R.id.action_bar_overlay_layout);
+ if (abol != null) {
+ abol.setOverlayMode(
+ (localFeatures & (1 << FEATURE_ACTION_BAR_OVERLAY)) != 0);
+ }
+
boolean splitActionBar = false;
final boolean splitWhenNarrow =
(mUiOptions & ActivityInfo.UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW) != 0;