summaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
authorSelim Cinek <cinek@google.com>2014-09-11 15:11:00 +0200
committerSelim Cinek <cinek@google.com>2014-09-15 17:25:40 +0200
commit92d892c0cd5462237f818b1129d936d95640e297 (patch)
treeac4e427a35fc7bd41fdb701c66aaedb2126bdfe8 /packages
parent2047df6f5f6af14cdb93f220c0329f1bff7a43ff (diff)
downloadframeworks_base-92d892c0cd5462237f818b1129d936d95640e297.zip
frameworks_base-92d892c0cd5462237f818b1129d936d95640e297.tar.gz
frameworks_base-92d892c0cd5462237f818b1129d936d95640e297.tar.bz2
Changed the swipe up search affordance
The previous card animation is removed and replaced by a animating circle with a shadow. Also fixes several cases where the card could either get stuck and the affordance was not launched. Bug: 17457300 Bug: 17444236 Change-Id: I005313a1dbe63d338490e6100dd3bd01e35687ba
Diffstat (limited to 'packages')
-rw-r--r--packages/SystemUI/res/anim/search_launch_enter.xml18
-rw-r--r--packages/SystemUI/res/drawable/search_panel_card_bg.xml21
-rw-r--r--packages/SystemUI/res/layout/status_bar_search_panel.xml11
-rw-r--r--packages/SystemUI/res/values-land/styles.xml12
-rw-r--r--packages/SystemUI/res/values-sw600dp/styles.xml10
-rw-r--r--packages/SystemUI/res/values/colors.xml3
-rw-r--r--packages/SystemUI/res/values/dimens.xml19
-rw-r--r--packages/SystemUI/res/values/styles.xml11
-rw-r--r--packages/SystemUI/src/com/android/systemui/SearchPanelCircleView.java592
-rw-r--r--packages/SystemUI/src/com/android/systemui/SearchPanelView.java161
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java46
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarViewTaskSwitchHelper.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java2
14 files changed, 702 insertions, 215 deletions
diff --git a/packages/SystemUI/res/anim/search_launch_enter.xml b/packages/SystemUI/res/anim/search_launch_enter.xml
index f3333b7..19c0a95 100644
--- a/packages/SystemUI/res/anim/search_launch_enter.xml
+++ b/packages/SystemUI/res/anim/search_launch_enter.xml
@@ -17,16 +17,8 @@
*/
-->
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:shareInterpolator="false" android:zAdjustment="top">
-
- <alpha android:fromAlpha="0" android:toAlpha="1.0"
- android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
- android:interpolator="@android:interpolator/decelerate_cubic"
- android:duration="300"/>
-
- <translate android:fromYDelta="100%" android:toYDelta="0"
- android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
- android:interpolator="@android:interpolator/decelerate_cubic"
- android:duration="300" />
-</set>
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+ android:fromAlpha="0" android:toAlpha="1.0"
+ android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+ android:interpolator="@android:interpolator/decelerate_cubic"
+ android:duration="300"/> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/search_panel_card_bg.xml b/packages/SystemUI/res/drawable/search_panel_card_bg.xml
deleted file mode 100644
index c19f900..0000000
--- a/packages/SystemUI/res/drawable/search_panel_card_bg.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- ~ Copyright (C) 2014 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
- <solid android:color="@color/search_panel_card_color" />
- <corners android:radius="@dimen/notification_material_rounded_rect_radius" />
-</shape>
diff --git a/packages/SystemUI/res/layout/status_bar_search_panel.xml b/packages/SystemUI/res/layout/status_bar_search_panel.xml
index f025abd..e0520ef 100644
--- a/packages/SystemUI/res/layout/status_bar_search_panel.xml
+++ b/packages/SystemUI/res/layout/status_bar_search_panel.xml
@@ -30,17 +30,14 @@
android:id="@+id/search_panel_scrim"
android:background="@drawable/search_panel_scrim" />
- <FrameLayout
- style="@style/SearchPanelCard"
- android:id="@+id/search_panel_card"
- android:background="@drawable/search_panel_card_bg"
- android:elevation="12dp">
+ <com.android.systemui.SearchPanelCircleView
+ style="@style/SearchPanelCircle"
+ android:id="@+id/search_panel_circle">
<ImageView
- style="@style/SearchPanelLogo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/search_logo" />
- </FrameLayout>
+ </com.android.systemui.SearchPanelCircleView>
</com.android.systemui.SearchPanelView>
diff --git a/packages/SystemUI/res/values-land/styles.xml b/packages/SystemUI/res/values-land/styles.xml
index 682998d..e58fbb1 100644
--- a/packages/SystemUI/res/values-land/styles.xml
+++ b/packages/SystemUI/res/values-land/styles.xml
@@ -19,18 +19,6 @@
<item name="android:layout_width">360dp</item>
</style>
- <style name="SearchPanelCard">
- <item name="android:layout_width">@dimen/search_panel_card_height</item>
- <item name="android:layout_height">match_parent</item>
- <item name="android:layout_marginTop">16dp</item>
- <item name="android:layout_marginBottom">16dp</item>
- <item name="android:layout_gravity">right</item>
- </style>
-
- <style name="SearchPanelLogo">
- <item name="android:layout_gravity">top|left</item>
- </style>
-
<style name="SearchPanelScrim">
<item name="android:layout_width">@dimen/search_panel_scrim_height</item>
<item name="android:layout_height">match_parent</item>
diff --git a/packages/SystemUI/res/values-sw600dp/styles.xml b/packages/SystemUI/res/values-sw600dp/styles.xml
index 9e5b1d6..156fa65 100644
--- a/packages/SystemUI/res/values-sw600dp/styles.xml
+++ b/packages/SystemUI/res/values-sw600dp/styles.xml
@@ -19,16 +19,6 @@
<item name="android:layout_width">480dp</item>
</style>
- <style name="SearchPanelCard">
- <item name="android:layout_width">550dp</item>
- <item name="android:layout_height">@dimen/search_panel_card_height</item>
- <item name="android:layout_gravity">center_horizontal|bottom</item>
- </style>
-
- <style name="SearchPanelLogo">
- <item name="android:layout_gravity">top|center_horizontal</item>
- </style>
-
<style name="SearchPanelScrim">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">@dimen/search_panel_scrim_height</item>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 6da811f..d5b0f17 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -109,7 +109,8 @@
<color name="notification_guts_text_color">#b2FFFFFF</color>
<color name="notification_guts_btn_color">#FFFFFFFF</color>
- <color name="search_panel_card_color">#ffffff</color>
+ <color name="search_panel_circle_color">#ffffff</color>
+ <color name="search_panel_ripple_color">#ffbbbbbb</color>
<color name="keyguard_user_switcher_background_gradient_color">#77000000</color>
<color name="doze_small_icon_background_color">#ff434343</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 4495318..8fe0af8 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -434,15 +434,20 @@
from Keyguard. -->
<dimen name="go_to_full_shade_appearing_translation">200dp</dimen>
- <!-- The height of the search panel card. -->
- <dimen name="search_panel_card_height">300dp</dimen>
+ <!-- The diameter of the search panel circle. -->
+ <dimen name="search_panel_circle_size">88dp</dimen>
- <!-- The height of the scrim behind the search panel card. -->
- <dimen name="search_panel_scrim_height">250dp</dimen>
+ <!-- The margin to the edge of the screen from where the circle starts to appear -->
+ <dimen name="search_panel_circle_base_margin">80dp</dimen>
+
+ <!-- The amount the circle translates when appearing -->
+ <dimen name="search_panel_circle_travel_distance">80dp</dimen>
- <!-- How much from the bottom of the screen the card should peek in when activating the search
- panel -->
- <dimen name="search_card_peek_height">100dp</dimen>
+ <!-- The elevation of the search panel circle -->
+ <dimen name="search_panel_circle_elevation">12dp</dimen>
+
+ <!-- The height of the scrim behind the search panel circle. -->
+ <dimen name="search_panel_scrim_height">250dp</dimen>
<!-- How far the user needs to drag up to invoke search. -->
<dimen name="search_panel_threshold">100dp</dimen>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index cb66e7a..0456c82 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -239,16 +239,9 @@
<item name="android:textColor">#60000000</item>
</style>
- <style name="SearchPanelCard">
+ <style name="SearchPanelCircle">
<item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">@dimen/search_panel_card_height</item>
- <item name="android:layout_marginStart">8dp</item>
- <item name="android:layout_marginEnd">8dp</item>
- <item name="android:layout_gravity">bottom</item>
- </style>
-
- <style name="SearchPanelLogo">
- <item name="android:layout_gravity">top|center_horizontal</item>
+ <item name="android:layout_height">match_parent</item>
</style>
<style name="SearchPanelScrim">
diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelCircleView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelCircleView.java
new file mode 100644
index 0000000..d8fb6da
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/SearchPanelCircleView.java
@@ -0,0 +1,592 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Outline;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewOutlineProvider;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+import android.view.animation.LinearInterpolator;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
+
+import java.util.ArrayList;
+
+public class SearchPanelCircleView extends FrameLayout {
+
+ private final int mCircleMinSize;
+ private final int mBaseMargin;
+ private final int mStaticOffset;
+ private final Paint mBackgroundPaint = new Paint();
+ private final Paint mRipplePaint = new Paint();
+ private final Rect mCircleRect = new Rect();
+ private final Rect mStaticRect = new Rect();
+ private final Interpolator mFastOutSlowInInterpolator;
+ private final Interpolator mAppearInterpolator;
+ private final Interpolator mDisappearInterpolator;
+
+ private boolean mClipToOutline;
+ private final int mMaxElevation;
+ private boolean mAnimatingOut;
+ private float mOutlineAlpha;
+ private float mOffset;
+ private float mCircleSize;
+ private boolean mHorizontal;
+ private boolean mCircleHidden;
+ private ImageView mLogo;
+ private boolean mDraggedFarEnough;
+ private boolean mOffsetAnimatingIn;
+ private float mCircleAnimationEndValue;
+ private ArrayList<Ripple> mRipples = new ArrayList<Ripple>();
+
+ private ValueAnimator mOffsetAnimator;
+ private ValueAnimator mCircleAnimator;
+ private ValueAnimator mFadeOutAnimator;
+ private ValueAnimator.AnimatorUpdateListener mCircleUpdateListener
+ = new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ applyCircleSize((float) animation.getAnimatedValue());
+ updateElevation();
+ }
+ };
+ private AnimatorListenerAdapter mClearAnimatorListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mCircleAnimator = null;
+ }
+ };
+ private ValueAnimator.AnimatorUpdateListener mOffsetUpdateListener
+ = new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ setOffset((float) animation.getAnimatedValue());
+ }
+ };
+
+
+ public SearchPanelCircleView(Context context) {
+ this(context, null);
+ }
+
+ public SearchPanelCircleView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public SearchPanelCircleView(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public SearchPanelCircleView(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ setOutlineProvider(new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ if (mCircleSize > 0.0f) {
+ outline.setOval(mCircleRect);
+ } else {
+ outline.setEmpty();
+ }
+ outline.setAlpha(mOutlineAlpha);
+ }
+ });
+ setWillNotDraw(false);
+ mCircleMinSize = context.getResources().getDimensionPixelSize(
+ R.dimen.search_panel_circle_size);
+ mBaseMargin = context.getResources().getDimensionPixelSize(
+ R.dimen.search_panel_circle_base_margin);
+ mStaticOffset = context.getResources().getDimensionPixelSize(
+ R.dimen.search_panel_circle_travel_distance);
+ mMaxElevation = context.getResources().getDimensionPixelSize(
+ R.dimen.search_panel_circle_elevation);
+ mAppearInterpolator = AnimationUtils.loadInterpolator(mContext,
+ android.R.interpolator.linear_out_slow_in);
+ mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(mContext,
+ android.R.interpolator.fast_out_slow_in);
+ mDisappearInterpolator = AnimationUtils.loadInterpolator(mContext,
+ android.R.interpolator.fast_out_linear_in);
+ mBackgroundPaint.setAntiAlias(true);
+ mBackgroundPaint.setColor(getResources().getColor(R.color.search_panel_circle_color));
+ mRipplePaint.setColor(getResources().getColor(R.color.search_panel_ripple_color));
+ mRipplePaint.setAntiAlias(true);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ drawBackground(canvas);
+ drawRipples(canvas);
+ }
+
+ private void drawRipples(Canvas canvas) {
+ for (int i = 0; i < mRipples.size(); i++) {
+ Ripple ripple = mRipples.get(i);
+ ripple.draw(canvas);
+ }
+ }
+
+ private void drawBackground(Canvas canvas) {
+ canvas.drawCircle(mCircleRect.centerX(), mCircleRect.centerY(), mCircleSize / 2,
+ mBackgroundPaint);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mLogo = (ImageView) findViewById(R.id.search_logo);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ mLogo.layout(0, 0, mLogo.getMeasuredWidth(), mLogo.getMeasuredHeight());
+ if (changed) {
+ updateCircleRect(mStaticRect, mStaticOffset, true);
+ }
+ }
+
+ public void setCircleSize(float circleSize) {
+ setCircleSize(circleSize, false, null, 0, null);
+ }
+
+ public void setCircleSize(float circleSize, boolean animated, final Runnable endRunnable,
+ int startDelay, Interpolator interpolator) {
+ boolean isAnimating = mCircleAnimator != null;
+ boolean animationPending = isAnimating && !mCircleAnimator.isRunning();
+ boolean animatingOut = isAnimating && mCircleAnimationEndValue == 0;
+ if (animated || animationPending || animatingOut) {
+ if (isAnimating) {
+ if (circleSize == mCircleAnimationEndValue) {
+ return;
+ }
+ mCircleAnimator.cancel();
+ }
+ mCircleAnimator = ValueAnimator.ofFloat(mCircleSize, circleSize);
+ mCircleAnimator.addUpdateListener(mCircleUpdateListener);
+ mCircleAnimator.addListener(mClearAnimatorListener);
+ mCircleAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (endRunnable != null) {
+ endRunnable.run();
+ }
+ }
+ });
+ Interpolator desiredInterpolator = interpolator != null ? interpolator
+ : circleSize == 0 ? mDisappearInterpolator : mAppearInterpolator;
+ mCircleAnimator.setInterpolator(desiredInterpolator);
+ mCircleAnimator.setDuration(300);
+ mCircleAnimator.setStartDelay(startDelay);
+ mCircleAnimator.start();
+ mCircleAnimationEndValue = circleSize;
+ } else {
+ if (isAnimating) {
+ float diff = circleSize - mCircleAnimationEndValue;
+ PropertyValuesHolder[] values = mCircleAnimator.getValues();
+ values[0].setFloatValues(diff, circleSize);
+ mCircleAnimator.setCurrentPlayTime(mCircleAnimator.getCurrentPlayTime());
+ mCircleAnimationEndValue = circleSize;
+ } else {
+ applyCircleSize(circleSize);
+ updateElevation();
+ }
+ }
+ }
+
+ private void applyCircleSize(float circleSize) {
+ mCircleSize = circleSize;
+ updateLayout();
+ }
+
+ private void updateElevation() {
+ float t = (mStaticOffset - mOffset) / (float) mStaticOffset;
+ t = 1.0f - Math.max(t, 0.0f);
+ float offset = t * mMaxElevation;
+ setElevation(offset);
+ }
+
+ /**
+ * Sets the offset to the edge of the screen. By default this not not animated.
+ *
+ * @param offset The offset to apply.
+ */
+ public void setOffset(float offset) {
+ setOffset(offset, false, 0, null, null);
+ }
+
+ /**
+ * Sets the offset to the edge of the screen.
+ *
+ * @param offset The offset to apply.
+ * @param animate Whether an animation should be performed.
+ * @param startDelay The desired start delay if animated.
+ * @param interpolator The desired interpolator if animated. If null,
+ * a default interpolator will be taken designed for appearing or
+ * disappearing.
+ * @param endRunnable The end runnable which should be executed when the animation is finished.
+ */
+ private void setOffset(float offset, boolean animate, int startDelay,
+ Interpolator interpolator, final Runnable endRunnable) {
+ if (!animate) {
+ mOffset = offset;
+ updateLayout();
+ if (endRunnable != null) {
+ endRunnable.run();
+ }
+ } else {
+ if (mOffsetAnimator != null) {
+ mOffsetAnimator.removeAllListeners();
+ mOffsetAnimator.cancel();
+ }
+ mOffsetAnimator = ValueAnimator.ofFloat(mOffset, offset);
+ mOffsetAnimator.addUpdateListener(mOffsetUpdateListener);
+ mOffsetAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mOffsetAnimator = null;
+ if (endRunnable != null) {
+ endRunnable.run();
+ }
+ }
+ });
+ Interpolator desiredInterpolator = interpolator != null ?
+ interpolator : offset == 0 ? mDisappearInterpolator : mAppearInterpolator;
+ mOffsetAnimator.setInterpolator(desiredInterpolator);
+ mOffsetAnimator.setStartDelay(startDelay);
+ mOffsetAnimator.setDuration(300);
+ mOffsetAnimator.start();
+ mOffsetAnimatingIn = offset != 0;
+ }
+ }
+
+ private void updateLayout() {
+ updateCircleRect();
+ updateLogo();
+ invalidateOutline();
+ invalidate();
+ updateClipping();
+ }
+
+ private void updateClipping() {
+ boolean clip = mCircleSize < mCircleMinSize || !mRipples.isEmpty();
+ if (clip != mClipToOutline) {
+ setClipToOutline(clip);
+ mClipToOutline = clip;
+ }
+ }
+
+ private void updateLogo() {
+ boolean exitAnimationRunning = mFadeOutAnimator != null;
+ Rect rect = exitAnimationRunning ? mCircleRect : mStaticRect;
+ float translationX = (rect.left + rect.right) / 2.0f - mLogo.getWidth() / 2.0f;
+ float translationY = (rect.top + rect.bottom) / 2.0f - mLogo.getHeight() / 2.0f;
+ float t = (mStaticOffset - mOffset) / (float) mStaticOffset;
+ if (!exitAnimationRunning) {
+ if (mHorizontal) {
+ translationX += t * mStaticOffset * 0.3f;
+ } else {
+ translationY += t * mStaticOffset * 0.3f;
+ }
+ float alpha = 1.0f-t;
+ alpha = Math.max((alpha - 0.5f) * 2.0f, 0);
+ mLogo.setAlpha(alpha);
+ } else {
+ translationY += (mOffset - mStaticOffset) / 2;
+ }
+ mLogo.setTranslationX(translationX);
+ mLogo.setTranslationY(translationY);
+ }
+
+ private void updateCircleRect() {
+ updateCircleRect(mCircleRect, mOffset, false);
+ }
+
+ private void updateCircleRect(Rect rect, float offset, boolean useStaticSize) {
+ int left, top;
+ float circleSize = useStaticSize ? mCircleMinSize : mCircleSize;
+ if (mHorizontal) {
+ left = (int) (getWidth() - circleSize / 2 - mBaseMargin - offset);
+ top = (int) ((getHeight() - circleSize) / 2);
+ } else {
+ left = (int) (getWidth() - circleSize) / 2;
+ top = (int) (getHeight() - circleSize / 2 - mBaseMargin - offset);
+ }
+ rect.set(left, top, (int) (left + circleSize), (int) (top + circleSize));
+ }
+
+ public void setHorizontal(boolean horizontal) {
+ mHorizontal = horizontal;
+ updateCircleRect(mStaticRect, mStaticOffset, true);
+ updateLayout();
+ }
+
+ public void setDragDistance(float distance) {
+ if (!mAnimatingOut && (!mCircleHidden || mDraggedFarEnough)) {
+ float circleSize = mCircleMinSize + rubberband(distance);
+ setCircleSize(circleSize);
+ }
+
+ }
+
+ private float rubberband(float diff) {
+ return (float) Math.pow(Math.abs(diff), 0.6f);
+ }
+
+ public void startAbortAnimation(Runnable endRunnable) {
+ if (mAnimatingOut) {
+ if (endRunnable != null) {
+ endRunnable.run();
+ }
+ return;
+ }
+ setCircleSize(0, true, null, 0, null);
+ setOffset(0, true, 0, null, endRunnable);
+ mCircleHidden = true;
+ }
+
+ public void startEnterAnimation() {
+ if (mAnimatingOut) {
+ return;
+ }
+ applyCircleSize(0);
+ setOffset(0);
+ setCircleSize(mCircleMinSize, true, null, 50, null);
+ setOffset(mStaticOffset, true, 50, null, null);
+ mCircleHidden = false;
+ }
+
+
+ public void startExitAnimation(final Runnable endRunnable) {
+ if (!mHorizontal) {
+ float offset = getHeight() / 2.0f;
+ setOffset(offset - mBaseMargin, true, 50, mFastOutSlowInInterpolator, null);
+ float xMax = getWidth() / 2;
+ float yMax = getHeight() / 2;
+ float maxRadius = (float) Math.ceil(Math.hypot(xMax, yMax) * 2);
+ setCircleSize(maxRadius, true, null, 50, mFastOutSlowInInterpolator);
+ performExitFadeOutAnimation(50, 300, endRunnable);
+ } else {
+
+ // when in landscape, we don't wan't the animation as it interferes with the general
+ // rotation animation to the homescreen.
+ endRunnable.run();
+ }
+ }
+
+ private void performExitFadeOutAnimation(int startDelay, int duration,
+ final Runnable endRunnable) {
+ mFadeOutAnimator = ValueAnimator.ofFloat(mBackgroundPaint.getAlpha() / 255.0f, 0.0f);
+
+ // Linear since we are animating multiple values
+ mFadeOutAnimator.setInterpolator(new LinearInterpolator());
+ mFadeOutAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ float animatedFraction = animation.getAnimatedFraction();
+ float logoValue = animatedFraction > 0.5f ? 1.0f : animatedFraction / 0.5f;
+ logoValue = PhoneStatusBar.ALPHA_OUT.getInterpolation(1.0f - logoValue);
+ float backgroundValue = animatedFraction < 0.2f ? 0.0f :
+ PhoneStatusBar.ALPHA_OUT.getInterpolation((animatedFraction - 0.2f) / 0.8f);
+ backgroundValue = 1.0f - backgroundValue;
+ mBackgroundPaint.setAlpha((int) (backgroundValue * 255));
+ mOutlineAlpha = backgroundValue;
+ mLogo.setAlpha(logoValue);
+ invalidateOutline();
+ invalidate();
+ }
+ });
+ mFadeOutAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (endRunnable != null) {
+ endRunnable.run();
+ }
+ mLogo.setAlpha(1.0f);
+ mBackgroundPaint.setAlpha(255);
+ mOutlineAlpha = 1.0f;
+ mFadeOutAnimator = null;
+ }
+ });
+ mFadeOutAnimator.setStartDelay(startDelay);
+ mFadeOutAnimator.setDuration(duration);
+ mFadeOutAnimator.start();
+ }
+
+ public void setDraggedFarEnough(boolean farEnough) {
+ if (farEnough != mDraggedFarEnough) {
+ if (farEnough) {
+ if (mCircleHidden) {
+ startEnterAnimation();
+ }
+ if (mOffsetAnimator == null) {
+ addRipple();
+ } else {
+ postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ addRipple();
+ }
+ }, 100);
+ }
+ } else {
+ startAbortAnimation(null);
+ }
+ mDraggedFarEnough = farEnough;
+ }
+
+ }
+
+ private void addRipple() {
+ if (mRipples.size() > 1) {
+ // we only want 2 ripples at the time
+ return;
+ }
+ float xInterpolation, yInterpolation;
+ if (mHorizontal) {
+ xInterpolation = 0.75f;
+ yInterpolation = 0.5f;
+ } else {
+ xInterpolation = 0.5f;
+ yInterpolation = 0.75f;
+ }
+ float circleCenterX = mStaticRect.left * (1.0f - xInterpolation)
+ + mStaticRect.right * xInterpolation;
+ float circleCenterY = mStaticRect.top * (1.0f - yInterpolation)
+ + mStaticRect.bottom * yInterpolation;
+ float radius = Math.max(mCircleSize, mCircleMinSize * 1.25f) * 0.75f;
+ Ripple ripple = new Ripple(circleCenterX, circleCenterY, radius);
+ ripple.start();
+ }
+
+ public void reset() {
+ mDraggedFarEnough = false;
+ mAnimatingOut = false;
+ mCircleHidden = true;
+ mClipToOutline = false;
+ if (mFadeOutAnimator != null) {
+ mFadeOutAnimator.cancel();
+ }
+ mBackgroundPaint.setAlpha(255);
+ mOutlineAlpha = 1.0f;
+ }
+
+ /**
+ * Check if an animation is currently running
+ *
+ * @param enterAnimation Is the animating queried the enter animation.
+ */
+ public boolean isAnimationRunning(boolean enterAnimation) {
+ return mOffsetAnimator != null && (enterAnimation == mOffsetAnimatingIn);
+ }
+
+ public void performOnAnimationFinished(final Runnable runnable) {
+ if (mOffsetAnimator != null) {
+ mOffsetAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (runnable != null) {
+ runnable.run();
+ }
+ }
+ });
+ } else {
+ if (runnable != null) {
+ runnable.run();
+ }
+ }
+ }
+
+ public void setAnimatingOut(boolean animatingOut) {
+ mAnimatingOut = animatingOut;
+ }
+
+ /**
+ * @return Whether the circle is currently launching to the search activity or aborting the
+ * interaction
+ */
+ public boolean isAnimatingOut() {
+ return mAnimatingOut;
+ }
+
+ @Override
+ public boolean hasOverlappingRendering() {
+ // not really true but it's ok during an animation, as it's never permanent
+ return false;
+ }
+
+ private class Ripple {
+ float x;
+ float y;
+ float radius;
+ float endRadius;
+ float alpha;
+
+ Ripple(float x, float y, float endRadius) {
+ this.x = x;
+ this.y = y;
+ this.endRadius = endRadius;
+ }
+
+ void start() {
+ ValueAnimator animator = ValueAnimator.ofFloat(0.0f, 1.0f);
+
+ // Linear since we are animating multiple values
+ animator.setInterpolator(new LinearInterpolator());
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ alpha = 1.0f - animation.getAnimatedFraction();
+ alpha = mDisappearInterpolator.getInterpolation(alpha);
+ radius = mAppearInterpolator.getInterpolation(animation.getAnimatedFraction());
+ radius *= endRadius;
+ invalidate();
+ }
+ });
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mRipples.remove(Ripple.this);
+ updateClipping();
+ }
+
+ public void onAnimationStart(Animator animation) {
+ mRipples.add(Ripple.this);
+ updateClipping();
+ }
+ });
+ animator.setDuration(400);
+ animator.start();
+ }
+
+ public void draw(Canvas canvas) {
+ mRipplePaint.setAlpha((int) (alpha * 255));
+ canvas.drawCircle(x, y, radius, mRipplePaint);
+ }
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
index 7d0ca14..445b499 100644
--- a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
@@ -16,10 +16,6 @@
package com.android.systemui;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
import android.app.ActivityOptions;
import android.app.SearchManager;
import android.content.ActivityNotFoundException;
@@ -38,8 +34,6 @@ import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
@@ -62,26 +56,19 @@ public class SearchPanelView extends FrameLayout implements StatusBarPanel {
private final Context mContext;
private BaseStatusBar mBar;
- private View mCard;
+ private SearchPanelCircleView mCircle;
private ImageView mLogo;
private View mScrim;
- private int mPeekHeight;
private int mThreshold;
private boolean mHorizontal;
- private final Interpolator mLinearOutSlowInInterpolator;
- private final Interpolator mFastOutLinearInInterpolator;
- private boolean mAnimatingIn;
- private boolean mAnimatingOut;
+ private boolean mLaunching;
private boolean mDragging;
private boolean mDraggedFarEnough;
private float mStartTouch;
private float mStartDrag;
-
- private ObjectAnimator mEnterAnimator;
-
- private boolean mStartExitAfterAnimatingIn;
+ private boolean mLaunchPending;
public SearchPanelView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
@@ -90,12 +77,7 @@ public class SearchPanelView extends FrameLayout implements StatusBarPanel {
public SearchPanelView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;
- mPeekHeight = context.getResources().getDimensionPixelSize(R.dimen.search_card_peek_height);
mThreshold = context.getResources().getDimensionPixelSize(R.dimen.search_panel_threshold);
- mLinearOutSlowInInterpolator =
- AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in);
- mFastOutLinearInInterpolator =
- AnimationUtils.loadInterpolator(context, android.R.interpolator.fast_out_linear_in);
}
private void startAssistActivity() {
@@ -128,7 +110,7 @@ public class SearchPanelView extends FrameLayout implements StatusBarPanel {
protected void onFinishInflate() {
super.onFinishInflate();
mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mCard = findViewById(R.id.search_panel_card);
+ mCircle = (SearchPanelCircleView) findViewById(R.id.search_panel_circle);
mLogo = (ImageView) findViewById(R.id.search_logo);
mScrim = findViewById(R.id.search_panel_scrim);
}
@@ -170,16 +152,9 @@ public class SearchPanelView extends FrameLayout implements StatusBarPanel {
v.setImageDrawable(null);
}
- private boolean pointInside(int x, int y, View v) {
- final int l = v.getLeft();
- final int r = v.getRight();
- final int t = v.getTop();
- final int b = v.getBottom();
- return x >= l && x < r && y >= t && y < b;
- }
-
+ @Override
public boolean isInContentArea(int x, int y) {
- return pointInside(x, y, mCard);
+ return true;
}
private void vibrate() {
@@ -199,16 +174,10 @@ public class SearchPanelView extends FrameLayout implements StatusBarPanel {
if (getVisibility() != View.VISIBLE) {
setVisibility(View.VISIBLE);
vibrate();
- mCard.setAlpha(1f);
if (animate) {
startEnterAnimation();
} else {
mScrim.setAlpha(1f);
- if (mHorizontal) {
- mCard.setX(getWidth() - mPeekHeight);
- } else {
- mCard.setY(getHeight() - mPeekHeight);
- }
}
}
setFocusable(true);
@@ -224,30 +193,7 @@ public class SearchPanelView extends FrameLayout implements StatusBarPanel {
}
private void startEnterAnimation() {
- if (mHorizontal) {
- mCard.setX(getWidth());
- } else {
- mCard.setY(getHeight());
- }
- mAnimatingIn = true;
- mCard.animate().cancel();
- mEnterAnimator = ObjectAnimator.ofFloat(mCard, mHorizontal ? View.X : View.Y,
- mHorizontal ? mCard.getX() : mCard.getY(),
- mHorizontal ? getWidth() - mPeekHeight : getHeight() - mPeekHeight);
- mEnterAnimator.setDuration(300);
- mEnterAnimator.setStartDelay(50);
- mEnterAnimator.setInterpolator(mLinearOutSlowInInterpolator);
- mEnterAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mEnterAnimator = null;
- mAnimatingIn = false;
- if (mStartExitAfterAnimatingIn) {
- startExitAnimation();
- }
- }
- });
- mEnterAnimator.start();
+ mCircle.startEnterAnimation();
mScrim.setAlpha(0f);
mScrim.animate()
.alpha(1f)
@@ -259,26 +205,17 @@ public class SearchPanelView extends FrameLayout implements StatusBarPanel {
}
private void startAbortAnimation() {
- mCard.animate().cancel();
- mAnimatingOut = true;
- if (mHorizontal) {
- mCard.animate().x(getWidth());
- } else {
- mCard.animate().y(getHeight());
- }
- mCard.animate()
- .setDuration(150)
- .setInterpolator(mFastOutLinearInInterpolator)
- .withEndAction(new Runnable() {
+ mCircle.startAbortAnimation(new Runnable() {
@Override
public void run() {
- mAnimatingOut = false;
+ mCircle.setAnimatingOut(false);
setVisibility(View.INVISIBLE);
}
});
+ mCircle.setAnimatingOut(true);
mScrim.animate()
.alpha(0f)
- .setDuration(150)
+ .setDuration(300)
.setStartDelay(0)
.setInterpolator(PhoneStatusBar.ALPHA_OUT);
}
@@ -314,7 +251,7 @@ public class SearchPanelView extends FrameLayout implements StatusBarPanel {
* when the animation is done.
*/
public boolean isShowing() {
- return getVisibility() == View.VISIBLE && !mAnimatingOut;
+ return getVisibility() == View.VISIBLE && !mCircle.isAnimatingOut();
}
public void setBar(BaseStatusBar bar) {
@@ -326,60 +263,46 @@ public class SearchPanelView extends FrameLayout implements StatusBarPanel {
.getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null;
}
- private float rubberband(float diff) {
- return Math.signum(diff) * (float) Math.pow(Math.abs(diff), 0.8f);
- }
-
@Override
public boolean onTouchEvent(MotionEvent event) {
+ if (mLaunching || mLaunchPending) {
+ return false;
+ }
int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
mStartTouch = mHorizontal ? event.getX() : event.getY();
mDragging = false;
mDraggedFarEnough = false;
- mStartExitAfterAnimatingIn = false;
+ mCircle.reset();
break;
case MotionEvent.ACTION_MOVE:
float currentTouch = mHorizontal ? event.getX() : event.getY();
if (getVisibility() == View.VISIBLE && !mDragging &&
- (!mAnimatingIn || Math.abs(mStartTouch - currentTouch) > mThreshold)) {
+ (!mCircle.isAnimationRunning(true /* enterAnimation */)
+ || Math.abs(mStartTouch - currentTouch) > mThreshold)) {
mStartDrag = currentTouch;
mDragging = true;
}
- if (!mDraggedFarEnough && Math.abs(mStartTouch - currentTouch) > mThreshold) {
- mDraggedFarEnough = true;
- }
if (mDragging) {
- if (!mAnimatingIn && !mAnimatingOut) {
- if (Math.abs(currentTouch - mStartDrag) > mThreshold) {
- startExitAnimation();
- } else {
- if (mHorizontal) {
- mCard.setX(getWidth() - mPeekHeight + rubberband(
- currentTouch - mStartDrag));
- } else {
- mCard.setY(getHeight() - mPeekHeight + rubberband(
- currentTouch - mStartDrag));
- }
- }
- } else if (mAnimatingIn ) {
- float diff = rubberband(currentTouch - mStartDrag);
- PropertyValuesHolder[] values = mEnterAnimator.getValues();
- values[0].setFloatValues(
- mHorizontal ? getWidth() + diff : getHeight() + diff,
- mHorizontal
- ? getWidth() - mPeekHeight + diff
- : getHeight() - mPeekHeight + diff);
- mEnterAnimator.setCurrentPlayTime(mEnterAnimator.getCurrentPlayTime());
- }
+ float offset = Math.max(mStartDrag - currentTouch, 0.0f);
+ mCircle.setDragDistance(offset);
+ mDraggedFarEnough = Math.abs(mStartTouch - currentTouch) > mThreshold;
+ mCircle.setDraggedFarEnough(mDraggedFarEnough);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (mDraggedFarEnough) {
- if (mAnimatingIn) {
- mStartExitAfterAnimatingIn = true;
+ if (mCircle.isAnimationRunning(true /* enterAnimation */)) {
+ mLaunchPending = true;
+ mCircle.setAnimatingOut(true);
+ mCircle.performOnAnimationFinished(new Runnable() {
+ @Override
+ public void run() {
+ startExitAnimation();
+ }
+ });
} else {
startExitAnimation();
}
@@ -392,35 +315,31 @@ public class SearchPanelView extends FrameLayout implements StatusBarPanel {
}
private void startExitAnimation() {
- if (mAnimatingOut || getVisibility() != View.VISIBLE) {
+ mLaunchPending = false;
+ if (mLaunching || getVisibility() != View.VISIBLE) {
return;
}
- if (mEnterAnimator != null) {
- mEnterAnimator.cancel();
- }
- mAnimatingOut = true;
+ mLaunching = true;
startAssistActivity();
vibrate();
- mCard.animate()
- .alpha(0f)
- .withLayer()
- .setDuration(250)
- .setInterpolator(PhoneStatusBar.ALPHA_OUT)
- .withEndAction(new Runnable() {
+ mCircle.setAnimatingOut(true);
+ mCircle.startExitAnimation(new Runnable() {
@Override
public void run() {
- mAnimatingOut = false;
+ mLaunching = false;
+ mCircle.setAnimatingOut(false);
setVisibility(View.INVISIBLE);
}
});
mScrim.animate()
.alpha(0f)
- .setDuration(250)
+ .setDuration(300)
.setStartDelay(0)
.setInterpolator(PhoneStatusBar.ALPHA_OUT);
}
public void setHorizontal(boolean horizontal) {
mHorizontal = horizontal;
+ mCircle.setHorizontal(horizontal);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index ce3739c..aa75fd4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -93,6 +93,7 @@ import com.android.systemui.SystemUI;
import com.android.systemui.statusbar.NotificationData.Entry;
import com.android.systemui.statusbar.phone.KeyguardTouchDelegate;
import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.statusbar.phone.NavigationBarView;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.HeadsUpNotificationView;
import com.android.systemui.statusbar.policy.PreviewInflater;
@@ -165,6 +166,9 @@ public abstract class BaseStatusBar extends SystemUI implements
protected int mLayoutDirection = -1; // invalid
protected AccessibilityManager mAccessibilityManager;
+
+ // on-screen navigation buttons
+ protected NavigationBarView mNavigationBarView = null;
private Locale mLocale;
private float mFontScale;
@@ -1006,6 +1010,8 @@ public abstract class BaseStatusBar extends SystemUI implements
mSearchPanelView.setOnTouchListener(
new TouchOutsideListener(MSG_CLOSE_SEARCH_PANEL, mSearchPanelView));
mSearchPanelView.setVisibility(View.GONE);
+ boolean vertical = mNavigationBarView != null && mNavigationBarView.isVertical();
+ mSearchPanelView.setHorizontal(vertical);
WindowManager.LayoutParams lp = getSearchLayoutParams(mSearchPanelView.getLayoutParams());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 0fb2192..3874b41 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -88,6 +88,7 @@ public class NavigationBarView extends LinearLayout {
private OnVerticalChangedListener mOnVerticalChangedListener;
private boolean mIsLayoutRtl;
+ private boolean mDelegateIntercepted;
private class NavTransitionListener implements TransitionListener {
private boolean mBackTransitioning;
@@ -198,27 +199,45 @@ public class NavigationBarView extends LinearLayout {
public void setOnVerticalChangedListener(OnVerticalChangedListener onVerticalChangedListener) {
mOnVerticalChangedListener = onVerticalChangedListener;
+ notifyVerticalChangedListener(mVertical);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
- if (mTaskSwitchHelper.onTouchEvent(event)) {
+ initDownStates(event);
+ if (!mDelegateIntercepted && mTaskSwitchHelper.onTouchEvent(event)) {
return true;
}
if (mDeadZone != null && event.getAction() == MotionEvent.ACTION_OUTSIDE) {
mDeadZone.poke(event);
}
- if (mDelegateHelper != null) {
+ if (mDelegateHelper != null && mDelegateIntercepted) {
boolean ret = mDelegateHelper.onInterceptTouchEvent(event);
if (ret) return true;
}
return super.onTouchEvent(event);
}
+ private void initDownStates(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ mDelegateIntercepted = false;
+ }
+ }
+
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
- return mTaskSwitchHelper.onInterceptTouchEvent(event) ||
- mDelegateHelper.onInterceptTouchEvent(event);
+ initDownStates(event);
+ boolean intercept = mTaskSwitchHelper.onInterceptTouchEvent(event);
+ if (!intercept) {
+ mDelegateIntercepted = mDelegateHelper.onInterceptTouchEvent(event);
+ intercept = mDelegateIntercepted;
+ } else {
+ MotionEvent cancelEvent = MotionEvent.obtain(event);
+ cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
+ mDelegateHelper.onInterceptTouchEvent(cancelEvent);
+ cancelEvent.recycle();
+ }
+ return intercept;
}
private H mHandler = new H();
@@ -426,12 +445,16 @@ public class NavigationBarView extends LinearLayout {
if (mDelegateHelper != null) {
mDelegateHelper.setSwapXY(mVertical);
}
- boolean isRTL = (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
- mTaskSwitchHelper.setBarState(mVertical, isRTL);
+ updateTaskSwitchHelper();
setNavigationIconHints(mNavigationIconHints, true);
}
+ private void updateTaskSwitchHelper() {
+ boolean isRtl = (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
+ mTaskSwitchHelper.setBarState(mVertical, isRtl);
+ }
+
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
@@ -448,19 +471,24 @@ public class NavigationBarView extends LinearLayout {
mVertical = newVertical;
//Log.v(TAG, String.format("onSizeChanged: h=%d, w=%d, vert=%s", h, w, mVertical?"y":"n"));
reorient();
- if (mOnVerticalChangedListener != null) {
- mOnVerticalChangedListener.onVerticalChanged(newVertical);
- }
+ notifyVerticalChangedListener(newVertical);
}
postCheckForInvalidLayout("sizeChanged");
super.onSizeChanged(w, h, oldw, oldh);
}
+ private void notifyVerticalChangedListener(boolean newVertical) {
+ if (mOnVerticalChangedListener != null) {
+ mOnVerticalChangedListener.onVerticalChanged(newVertical);
+ }
+ }
+
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
updateRTLOrder();
+ updateTaskSwitchHelper();
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarViewTaskSwitchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarViewTaskSwitchHelper.java
index 79bb1cd..c253e19 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarViewTaskSwitchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarViewTaskSwitchHelper.java
@@ -55,7 +55,7 @@ public class NavigationBarViewTaskSwitchHelper extends GestureDetector.SimpleOnG
// task switcher detector
mTaskSwitcherDetector.onTouchEvent(event);
int action = event.getAction();
- boolean interceptTouches = false;
+ boolean intercepted = false;
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
mTouchDownX = (int) event.getX();
@@ -71,7 +71,6 @@ public class NavigationBarViewTaskSwitchHelper extends GestureDetector.SimpleOnG
? xDiff > mScrollTouchSlop && xDiff > yDiff
: yDiff > mScrollTouchSlop && yDiff > xDiff;
if (exceededTouchSlop) {
- interceptTouches = true;
return true;
}
break;
@@ -80,7 +79,7 @@ public class NavigationBarViewTaskSwitchHelper extends GestureDetector.SimpleOnG
case MotionEvent.ACTION_UP:
break;
}
- return interceptTouches;
+ return intercepted;
}
public boolean onTouchEvent(MotionEvent event) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index e6db2c8..4272582 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -316,8 +316,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
int[] mPositionTmp = new int[2];
boolean mExpandedVisible;
- // on-screen navigation buttons
- private NavigationBarView mNavigationBarView = null;
private int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
// the tracker view