am ed097689: Merge "Add animations for the system bar color views" into lmp-mr1-dev

* commit 'ed0976897a8d8eb1f7bf55ae25aece84b172cbb4':
  Add animations for the system bar color views
This commit is contained in:
Adrian Roos
2014-11-18 20:26:14 +00:00
committed by Android Git Automerger
7 changed files with 139 additions and 44 deletions

View File

@@ -20,5 +20,5 @@
<set xmlns:android="http://schemas.android.com/apk/res/android" <set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/decelerate_cubic"> android:interpolator="@android:interpolator/decelerate_cubic">
<translate android:fromYDelta="100%" android:toYDelta="0" <translate android:fromYDelta="100%" android:toYDelta="0"
android:duration="250"/> android:duration="@integer/dock_enter_exit_duration"/>
</set> </set>

View File

@@ -20,5 +20,5 @@
<set xmlns:android="http://schemas.android.com/apk/res/android" <set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/accelerate_cubic"> android:interpolator="@android:interpolator/accelerate_cubic">
<translate android:fromYDelta="0" android:toYDelta="100%" <translate android:fromYDelta="0" android:toYDelta="100%"
android:startOffset="100" android:duration="250"/> android:startOffset="100" android:duration="@integer/dock_enter_exit_duration"/>
</set> </set>

View File

@@ -20,5 +20,5 @@
<set xmlns:android="http://schemas.android.com/apk/res/android" <set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/decelerate_cubic"> android:interpolator="@android:interpolator/decelerate_cubic">
<translate android:fromYDelta="-100%" android:toYDelta="0" <translate android:fromYDelta="-100%" android:toYDelta="0"
android:duration="250"/> android:duration="@integer/dock_enter_exit_duration"/>
</set> </set>

View File

@@ -20,5 +20,5 @@
<set xmlns:android="http://schemas.android.com/apk/res/android" <set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/accelerate_cubic"> android:interpolator="@android:interpolator/accelerate_cubic">
<translate android:fromYDelta="0" android:toYDelta="-100%" <translate android:fromYDelta="0" android:toYDelta="-100%"
android:startOffset="100" android:duration="250"/> android:startOffset="100" android:duration="@integer/dock_enter_exit_duration"/>
</set> </set>

View File

@@ -22,4 +22,5 @@
<integer name="button_pressed_animation_duration">100</integer> <integer name="button_pressed_animation_duration">100</integer>
<integer name="button_pressed_animation_delay">100</integer> <integer name="button_pressed_animation_delay">100</integer>
<integer name="disabled_alpha_animation_duration">100</integer> <integer name="disabled_alpha_animation_duration">100</integer>
<integer name="dock_enter_exit_duration">250</integer>
</resources> </resources>

View File

@@ -1848,6 +1848,7 @@
<java-symbol type="string" name="usb_storage_stop_title" /> <java-symbol type="string" name="usb_storage_stop_title" />
<java-symbol type="string" name="usb_storage_title" /> <java-symbol type="string" name="usb_storage_title" />
<java-symbol type="style" name="Animation.RecentApplications" /> <java-symbol type="style" name="Animation.RecentApplications" />
<java-symbol type="integer" name="dock_enter_exit_duration" />
<!-- ImfTest --> <!-- ImfTest -->
<java-symbol type="layout" name="auto_complete_list" /> <java-symbol type="layout" name="auto_complete_list" />

View File

@@ -101,6 +101,7 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager;
import android.view.animation.Animation; import android.view.animation.Animation;
import android.view.animation.AnimationUtils; import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.PopupWindow; import android.widget.PopupWindow;
@@ -2153,6 +2154,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
} }
private final class DecorView extends FrameLayout implements RootViewSurfaceTaker { private final class DecorView extends FrameLayout implements RootViewSurfaceTaker {
/* package */int mDefaultOpacity = PixelFormat.OPAQUE; /* package */int mDefaultOpacity = PixelFormat.OPAQUE;
/** The feature ID of the panel, or -1 if this is the application's DecorView */ /** The feature ID of the panel, or -1 if this is the application's DecorView */
@@ -2182,19 +2184,45 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
// View added at runtime to draw under the navigation bar area // View added at runtime to draw under the navigation bar area
private View mNavigationGuard; private View mNavigationGuard;
private View mStatusColorView; private final ColorViewState mStatusColorViewState = new ColorViewState(
private View mNavigationColorView; SYSTEM_UI_FLAG_FULLSCREEN, FLAG_TRANSLUCENT_STATUS,
Gravity.TOP,
STATUS_BAR_BACKGROUND_TRANSITION_NAME,
com.android.internal.R.id.statusBarBackground,
FLAG_FULLSCREEN);
private final ColorViewState mNavigationColorViewState = new ColorViewState(
SYSTEM_UI_FLAG_HIDE_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION,
Gravity.BOTTOM,
NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME,
com.android.internal.R.id.navigationBarBackground,
0 /* hideWindowFlag */);
private final Interpolator mShowInterpolator;
private final Interpolator mHideInterpolator;
private final int mBarEnterExitDuration;
private final BackgroundFallback mBackgroundFallback = new BackgroundFallback(); private final BackgroundFallback mBackgroundFallback = new BackgroundFallback();
private int mLastTopInset = 0; private int mLastTopInset = 0;
private int mLastBottomInset = 0; private int mLastBottomInset = 0;
private int mLastRightInset = 0; private int mLastRightInset = 0;
private boolean mLastHasTopStableInset = false;
private boolean mLastHasBottomStableInset = false;
private int mLastWindowFlags = 0;
private int mRootScrollY = 0; private int mRootScrollY = 0;
public DecorView(Context context, int featureId) { public DecorView(Context context, int featureId) {
super(context); super(context);
mFeatureId = featureId; mFeatureId = featureId;
mShowInterpolator = AnimationUtils.loadInterpolator(context,
android.R.interpolator.linear_out_slow_in);
mHideInterpolator = AnimationUtils.loadInterpolator(context,
android.R.interpolator.fast_out_linear_in);
mBarEnterExitDuration = context.getResources().getInteger(
R.integer.dock_enter_exit_duration);
} }
public void setBackgroundFallback(int resId) { public void setBackgroundFallback(int resId) {
@@ -2787,13 +2815,13 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
@Override @Override
public void onWindowSystemUiVisibilityChanged(int visible) { public void onWindowSystemUiVisibilityChanged(int visible) {
updateColorViews(null /* insets */); updateColorViews(null /* insets */, true /* animate */);
} }
@Override @Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) { public WindowInsets onApplyWindowInsets(WindowInsets insets) {
mFrameOffsets.set(insets.getSystemWindowInsets()); mFrameOffsets.set(insets.getSystemWindowInsets());
insets = updateColorViews(insets); insets = updateColorViews(insets, true /* animate */);
insets = updateStatusGuard(insets); insets = updateStatusGuard(insets);
updateNavigationGuard(insets); updateNavigationGuard(insets);
if (getForeground() != null) { if (getForeground() != null) {
@@ -2807,11 +2835,16 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
return false; return false;
} }
private WindowInsets updateColorViews(WindowInsets insets) { private WindowInsets updateColorViews(WindowInsets insets, boolean animate) {
WindowManager.LayoutParams attrs = getAttributes(); WindowManager.LayoutParams attrs = getAttributes();
int sysUiVisibility = attrs.systemUiVisibility | getWindowSystemUiVisibility(); int sysUiVisibility = attrs.systemUiVisibility | getWindowSystemUiVisibility();
if (!mIsFloating && ActivityManager.isHighEndGfx()) { if (!mIsFloating && ActivityManager.isHighEndGfx()) {
boolean disallowAnimate = !isLaidOut();
disallowAnimate |= ((mLastWindowFlags ^ attrs.flags)
& FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
mLastWindowFlags = attrs.flags;
if (insets != null) { if (insets != null) {
mLastTopInset = Math.min(insets.getStableInsetTop(), mLastTopInset = Math.min(insets.getStableInsetTop(),
insets.getSystemWindowInsetTop()); insets.getSystemWindowInsetTop());
@@ -2819,19 +2852,23 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
insets.getSystemWindowInsetBottom()); insets.getSystemWindowInsetBottom());
mLastRightInset = Math.min(insets.getStableInsetRight(), mLastRightInset = Math.min(insets.getStableInsetRight(),
insets.getSystemWindowInsetRight()); insets.getSystemWindowInsetRight());
// Don't animate if the presence of stable insets has changed, because that
// indicates that the window was either just added and received them for the
// first time, or the window size or position has changed.
boolean hasTopStableInset = insets.getStableInsetTop() != 0;
disallowAnimate |= hasTopStableInset && !mLastHasTopStableInset;
mLastHasTopStableInset = hasTopStableInset;
boolean hasBottomStableInset = insets.getStableInsetBottom() != 0;
disallowAnimate |= hasBottomStableInset && !mLastHasBottomStableInset;
mLastHasBottomStableInset = hasBottomStableInset;
} }
mStatusColorView = updateColorViewInt(mStatusColorView, sysUiVisibility,
SYSTEM_UI_FLAG_FULLSCREEN, FLAG_TRANSLUCENT_STATUS, updateColorViewInt(mStatusColorViewState, sysUiVisibility, mStatusBarColor,
mStatusBarColor, mLastTopInset, Gravity.TOP, mLastTopInset, animate && !disallowAnimate);
STATUS_BAR_BACKGROUND_TRANSITION_NAME, updateColorViewInt(mNavigationColorViewState, sysUiVisibility, mNavigationBarColor,
com.android.internal.R.id.statusBarBackground, mLastBottomInset, animate && !disallowAnimate);
(getAttributes().flags & FLAG_FULLSCREEN) != 0);
mNavigationColorView = updateColorViewInt(mNavigationColorView, sysUiVisibility,
SYSTEM_UI_FLAG_HIDE_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION,
mNavigationBarColor, mLastBottomInset, Gravity.BOTTOM,
NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME,
com.android.internal.R.id.navigationBarBackground,
false /* hiddenByWindowFlag */);
} }
// When we expand the window with FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, we still need // When we expand the window with FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, we still need
@@ -2875,28 +2912,35 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
return insets; return insets;
} }
private View updateColorViewInt(View view, int sysUiVis, int systemUiHideFlag, private void updateColorViewInt(final ColorViewState state, int sysUiVis, int color,
int translucentFlag, int color, int height, int verticalGravity, int height, boolean animate) {
String transitionName, int id, boolean hiddenByWindowFlag) { boolean show = height > 0 && (sysUiVis & state.systemUiHideFlag) == 0
boolean show = height > 0 && (sysUiVis & systemUiHideFlag) == 0 && (getAttributes().flags & state.hideWindowFlag) == 0
&& !hiddenByWindowFlag && (getAttributes().flags & state.translucentFlag) == 0
&& (getAttributes().flags & translucentFlag) == 0
&& (color & Color.BLACK) != 0 && (color & Color.BLACK) != 0
&& (getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0; && (getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
boolean visibilityChanged = false;
View view = state.view;
if (view == null) { if (view == null) {
if (show) { if (show) {
view = new View(mContext); state.view = view = new View(mContext);
view.setBackgroundColor(color); view.setBackgroundColor(color);
view.setTransitionName(transitionName); view.setTransitionName(state.transitionName);
view.setId(id); view.setId(state.id);
visibilityChanged = true;
view.setVisibility(INVISIBLE);
state.targetVisibility = VISIBLE;
addView(view, new LayoutParams(LayoutParams.MATCH_PARENT, height, addView(view, new LayoutParams(LayoutParams.MATCH_PARENT, height,
Gravity.START | verticalGravity)); Gravity.START | state.verticalGravity));
updateColorViewTranslations(); updateColorViewTranslations();
} }
} else { } else {
int vis = show ? VISIBLE : INVISIBLE; int vis = show ? VISIBLE : INVISIBLE;
view.setVisibility(vis); visibilityChanged = state.targetVisibility != vis;
state.targetVisibility = vis;
if (show) { if (show) {
LayoutParams lp = (LayoutParams) view.getLayoutParams(); LayoutParams lp = (LayoutParams) view.getLayoutParams();
if (lp.height != height) { if (lp.height != height) {
@@ -2906,18 +2950,43 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
view.setBackgroundColor(color); view.setBackgroundColor(color);
} }
} }
return view; if (visibilityChanged) {
view.animate().cancel();
if (animate) {
if (show) {
if (view.getVisibility() != VISIBLE) {
view.setVisibility(VISIBLE);
view.setAlpha(0.0f);
}
view.animate().alpha(1.0f).setInterpolator(mShowInterpolator).
setDuration(mBarEnterExitDuration);
} else {
view.animate().alpha(0.0f).setInterpolator(mHideInterpolator)
.setDuration(mBarEnterExitDuration)
.withEndAction(new Runnable() {
@Override
public void run() {
state.view.setAlpha(1.0f);
state.view.setVisibility(INVISIBLE);
}
});
}
} else {
view.setAlpha(1.0f);
view.setVisibility(show ? VISIBLE : INVISIBLE);
}
}
} }
private void updateColorViewTranslations() { private void updateColorViewTranslations() {
// Put the color views back in place when they get moved off the screen // Put the color views back in place when they get moved off the screen
// due to the the ViewRootImpl panning. // due to the the ViewRootImpl panning.
int rootScrollY = mRootScrollY; int rootScrollY = mRootScrollY;
if (mStatusColorView != null) { if (mStatusColorViewState.view != null) {
mStatusColorView.setTranslationY(rootScrollY > 0 ? rootScrollY : 0); mStatusColorViewState.view.setTranslationY(rootScrollY > 0 ? rootScrollY : 0);
} }
if (mNavigationColorView != null) { if (mNavigationColorViewState.view != null) {
mNavigationColorView.setTranslationY(rootScrollY < 0 ? rootScrollY : 0); mNavigationColorViewState.view.setTranslationY(rootScrollY < 0 ? rootScrollY : 0);
} }
} }
@@ -2948,7 +3017,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
mStatusGuard = new View(mContext); mStatusGuard = new View(mContext);
mStatusGuard.setBackgroundColor(mContext.getResources() mStatusGuard.setBackgroundColor(mContext.getResources()
.getColor(R.color.input_method_navigation_guard)); .getColor(R.color.input_method_navigation_guard));
addView(mStatusGuard, indexOfChild(mStatusColorView), addView(mStatusGuard, indexOfChild(mStatusColorViewState.view),
new LayoutParams(LayoutParams.MATCH_PARENT, new LayoutParams(LayoutParams.MATCH_PARENT,
mlp.topMargin, Gravity.START | Gravity.TOP)); mlp.topMargin, Gravity.START | Gravity.TOP));
} else { } else {
@@ -3008,8 +3077,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
mNavigationGuard = new View(mContext); mNavigationGuard = new View(mContext);
mNavigationGuard.setBackgroundColor(mContext.getResources() mNavigationGuard.setBackgroundColor(mContext.getResources()
.getColor(R.color.input_method_navigation_guard)); .getColor(R.color.input_method_navigation_guard));
addView(mNavigationGuard, indexOfChild(mNavigationColorView), new LayoutParams( addView(mNavigationGuard, indexOfChild(mNavigationColorViewState.view),
LayoutParams.MATCH_PARENT, insets.getSystemWindowInsetBottom(), new LayoutParams(LayoutParams.MATCH_PARENT,
insets.getSystemWindowInsetBottom(),
Gravity.START | Gravity.BOTTOM)); Gravity.START | Gravity.BOTTOM));
} else { } else {
LayoutParams lp = (LayoutParams) mNavigationGuard.getLayoutParams(); LayoutParams lp = (LayoutParams) mNavigationGuard.getLayoutParams();
@@ -3912,7 +3982,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
protected void dispatchWindowAttributesChanged(WindowManager.LayoutParams attrs) { protected void dispatchWindowAttributesChanged(WindowManager.LayoutParams attrs) {
super.dispatchWindowAttributesChanged(attrs); super.dispatchWindowAttributesChanged(attrs);
if (mDecor != null) { if (mDecor != null) {
mDecor.updateColorViews(null /* insets */); mDecor.updateColorViews(null /* insets */, true /* animate */);
} }
} }
@@ -4639,6 +4709,29 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
} }
} }
private static class ColorViewState {
View view = null;
int targetVisibility = View.INVISIBLE;
final int id;
final int systemUiHideFlag;
final int translucentFlag;
final int verticalGravity;
final String transitionName;
final int hideWindowFlag;
ColorViewState(int systemUiHideFlag,
int translucentFlag, int verticalGravity,
String transitionName, int id, int hideWindowFlag) {
this.id = id;
this.systemUiHideFlag = systemUiHideFlag;
this.translucentFlag = translucentFlag;
this.verticalGravity = verticalGravity;
this.transitionName = transitionName;
this.hideWindowFlag = hideWindowFlag;
}
}
void sendCloseSystemWindows() { void sendCloseSystemWindows() {
PhoneWindowManager.sendCloseSystemWindows(getContext(), null); PhoneWindowManager.sendCloseSystemWindows(getContext(), null);
} }
@@ -4657,7 +4750,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
mStatusBarColor = color; mStatusBarColor = color;
mForcedStatusBarColor = true; mForcedStatusBarColor = true;
if (mDecor != null) { if (mDecor != null) {
mDecor.updateColorViews(null); mDecor.updateColorViews(null, false /* animate */);
} }
} }
@@ -4671,7 +4764,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
mNavigationBarColor = color; mNavigationBarColor = color;
mForcedNavigationBarColor = true; mForcedNavigationBarColor = true;
if (mDecor != null) { if (mDecor != null) {
mDecor.updateColorViews(null); mDecor.updateColorViews(null, false /* animate */);
} }
} }
} }