Merge "Introduce better animation for incoming-call widget"
Daisuke Miyakawa [Fri, 2 Mar 2012 15:13:02 +0000 (07:13 -0800)]
res/layout/incall_touch_ui.xml
src/com/android/phone/AnimationUtils.java
src/com/android/phone/InCallTouchUi.java

index 7a685b3..2fd3de8 100644 (file)
      This layout is a fullscreen overlay, drawn on top of the
      non-touch-sensitive parts of the in-call UI (i.e. the call card).
 
-     The top-level View here is a FrameLayout with 2 children:
-       (1) incomingCallWidget: the UI displayed while an incoming call is ringing
-       (2) inCallControls: the widgets visible while a regular call (or calls) is in progress
-     Exactly one of these is visible at any given moment.
+     The top-level View here is a InCallTouchUi (FrameLayout) with 2 children:
+       (1) inCallControls: the widgets visible while a regular call (or calls) is in progress
+       (2) incomingCallWidget: the UI displayed while an incoming call is ringing
+     In usual cases, one of these is visible at any given moment.
+     One exception is when incomingCallWidget is fading-out. At that moment, we show
+     inCallControls beneath incomingCallWidget for smoother transition.
      -->
 <com.android.phone.InCallTouchUi xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
     >
 
     <!--
-        (1) incomingCallWidget: the UI displayed while an incoming call is ringing.
-            See InCallTouchUi.showIncomingCallWidget().
-
-            Layout notes:
-            - Use an opaque black background since we need to cover up
-              a bit of the bottom of the contact photo
-            - The verticalOffset value gets us a little extra space above
-              the topmost "Respond by SMS" icon
-            - The negative layout_marginBottom shifts us slightly downward;
-              we're already aligned with the bottom of the screen, but we
-              don't have an icon in the downward direction so the whole
-              bottom area of this widget is just wasted space.
-    -->
-    <com.android.internal.widget.multiwaveview.MultiWaveView
-        android:id="@+id/incomingCallWidget"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center|bottom"
-        android:layout_marginBottom="-46dp"
-        android:background="@android:color/black"
-        android:visibility="gone"
-
-        prvandroid:targetDrawables="@array/incoming_call_widget_3way_targets"
-        prvandroid:targetDescriptions="@array/incoming_call_widget_3way_target_descriptions"
-        prvandroid:directionDescriptions="@array/incoming_call_widget_3way_direction_descriptions"
-        prvandroid:handleDrawable="@drawable/ic_in_call_touch_handle"
-        prvandroid:waveDrawable="@*android:drawable/ic_lockscreen_outerring"
-        prvandroid:outerRadius="@*android:dimen/multiwaveview_target_placement_radius"
-        prvandroid:snapMargin="@*android:dimen/multiwaveview_snap_margin"
-        prvandroid:hitRadius="@*android:dimen/multiwaveview_hit_radius"
-        prvandroid:vibrationDuration="20"
-        prvandroid:leftChevronDrawable="@*android:drawable/ic_lockscreen_chevron_left"
-        prvandroid:rightChevronDrawable="@*android:drawable/ic_lockscreen_chevron_right"
-        prvandroid:feedbackCount="3"
-        prvandroid:horizontalOffset="0dip"
-        prvandroid:verticalOffset="20dip"
-        />
-
-    <!--
-        (2) inCallControls: the widgets visible while a regular call
+        (1) inCallControls: the widgets visible while a regular call
         (or calls) is in progress
     -->
     <RelativeLayout android:id="@+id/inCallControls"
 
     </RelativeLayout>
 
+    <!--
+        (2) incomingCallWidget: the UI displayed while an incoming call is ringing.
+            See InCallTouchUi.showIncomingCallWidget().
+
+            Layout notes:
+            - Use an opaque black background since we need to cover up
+              a bit of the bottom of the contact photo
+            - The verticalOffset value gets us a little extra space above
+              the topmost "Respond by SMS" icon
+            - The negative layout_marginBottom shifts us slightly downward;
+              we're already aligned with the bottom of the screen, but we
+              don't have an icon in the downward direction so the whole
+              bottom area of this widget is just wasted space.
+    -->
+    <com.android.internal.widget.multiwaveview.MultiWaveView
+        android:id="@+id/incomingCallWidget"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center|bottom"
+        android:layout_marginBottom="-46dp"
+        android:background="@android:color/black"
+        android:visibility="gone"
+
+        prvandroid:targetDrawables="@array/incoming_call_widget_3way_targets"
+        prvandroid:targetDescriptions="@array/incoming_call_widget_3way_target_descriptions"
+        prvandroid:directionDescriptions="@array/incoming_call_widget_3way_direction_descriptions"
+        prvandroid:handleDrawable="@drawable/ic_in_call_touch_handle"
+        prvandroid:waveDrawable="@*android:drawable/ic_lockscreen_outerring"
+        prvandroid:outerRadius="@*android:dimen/multiwaveview_target_placement_radius"
+        prvandroid:snapMargin="@*android:dimen/multiwaveview_snap_margin"
+        prvandroid:hitRadius="@*android:dimen/multiwaveview_hit_radius"
+        prvandroid:vibrationDuration="20"
+        prvandroid:leftChevronDrawable="@*android:drawable/ic_lockscreen_chevron_left"
+        prvandroid:rightChevronDrawable="@*android:drawable/ic_lockscreen_chevron_right"
+        prvandroid:feedbackCount="3"
+        prvandroid:horizontalOffset="0dip"
+        prvandroid:verticalOffset="20dip"
+        />
+
 </com.android.phone.InCallTouchUi>
index 9c2a2b5..ca3db50 100644 (file)
@@ -40,7 +40,7 @@ public class AnimationUtils {
      * Duration for animations in msec, which can be used with
      * {@link ViewPropertyAnimator#setDuration(long)} for example.
      */
-    private static final int ANIMATION_DURATION = 250;
+    public static final int ANIMATION_DURATION = 250;
 
     private AnimationUtils() {
     }
index 7598f53..2317cbf 100644 (file)
@@ -16,6 +16,8 @@
 
 package com.android.phone;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.content.Context;
 import android.graphics.drawable.LayerDrawable;
 import android.os.Handler;
@@ -30,6 +32,7 @@ import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewPropertyAnimator;
 import android.view.ViewStub;
 import android.view.animation.AlphaAnimation;
 import android.view.animation.Animation;
@@ -56,7 +59,6 @@ import com.android.phone.InCallUiState.InCallScreenMode;
 public class InCallTouchUi extends FrameLayout
         implements View.OnClickListener, View.OnLongClickListener, OnTriggerListener,
         PopupMenu.OnMenuItemClickListener, PopupMenu.OnDismissListener {
-    private static final int IN_CALL_WIDGET_TRANSITION_TIME = 250; // in ms
     private static final String LOG_TAG = "InCallTouchUi";
     private static final boolean DBG = (PhoneApp.DBG_LEVEL >= 2);
 
@@ -77,10 +79,12 @@ public class InCallTouchUi extends FrameLayout
 
     // UI containers / elements
     private MultiWaveView mIncomingCallWidget;  // UI used for an incoming call
-    private boolean mShowInCallControlsDuringHidingAnimation;
+    private boolean mIncomingCallWidgetIsFadingOut;
 
     /** UI elements while on a regular call (bottom buttons, DTMF dialpad) */
     private View mInCallControls;
+    private boolean mShowInCallControlsDuringHidingAnimation;
+
     //
     private ImageButton mAddButton;
     private ImageButton mMergeButton;
@@ -1041,7 +1045,7 @@ public class InCallTouchUi extends FrameLayout
     private void hideIncomingCallWidget() {
         if (DBG) log("hideIncomingCallWidget()...");
         if (mIncomingCallWidget.getVisibility() != View.VISIBLE
-                || mIncomingCallWidget.getAnimation() != null) {
+                || mIncomingCallWidgetIsFadingOut) {
             // Widget is already hidden or in the process of being hidden
             return;
         }
@@ -1050,11 +1054,13 @@ public class InCallTouchUi extends FrameLayout
         log("Start hiding IncomingCallWidget");
 
         // Hide the incoming call screen with a transition
-        AlphaAnimation anim = new AlphaAnimation(1.0f, 0.0f);
-        anim.setDuration(IN_CALL_WIDGET_TRANSITION_TIME);
-        anim.setAnimationListener(new AnimationListener() {
+        mIncomingCallWidgetIsFadingOut = true;
+        ViewPropertyAnimator animator = mIncomingCallWidget.animate();
+        animator.cancel();
+        animator.setDuration(AnimationUtils.ANIMATION_DURATION);
+        animator.setListener(new AnimatorListenerAdapter() {
             @Override
-            public void onAnimationStart(Animation animation) {
+            public void onAnimationStart(Animator animation) {
                 if (mShowInCallControlsDuringHidingAnimation) {
                     if (DBG) log("IncomingCallWidget's hiding animation started");
                     updateInCallControls(mApp.mCM);
@@ -1062,18 +1068,16 @@ public class InCallTouchUi extends FrameLayout
                 }
             }
             @Override
-            public void onAnimationRepeat(Animation animation) {
-            }
-            @Override
-            public void onAnimationEnd(Animation animation) {
+            public void onAnimationEnd(Animator animation) {
                 if (DBG) log("IncomingCallWidget's hiding animation ended");
-                // hide the incoming call UI.
-                mIncomingCallWidget.clearAnimation();
+                mIncomingCallWidget.setAlpha(1);
                 mIncomingCallWidget.setVisibility(View.GONE);
+                mIncomingCallWidget.animate().setListener(null);
                 mShowInCallControlsDuringHidingAnimation = false;
+                mIncomingCallWidgetIsFadingOut = false;
             }
         });
-        mIncomingCallWidget.startAnimation(anim);
+        animator.alpha(0f);
     }
 
     /**