diff options
Diffstat (limited to 'java/com/android/dialershared/bubble/Bubble.java')
-rw-r--r-- | java/com/android/dialershared/bubble/Bubble.java | 124 |
1 files changed, 81 insertions, 43 deletions
diff --git a/java/com/android/dialershared/bubble/Bubble.java b/java/com/android/dialershared/bubble/Bubble.java index f2ba117d8..9606f5be6 100644 --- a/java/com/android/dialershared/bubble/Bubble.java +++ b/java/com/android/dialershared/bubble/Bubble.java @@ -61,6 +61,8 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; import android.widget.ViewAnimator; +import com.android.dialer.logging.DialerImpression; +import com.android.dialer.logging.Logger; import com.android.dialershared.bubble.BubbleInfo.Action; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -87,6 +89,8 @@ public class Bubble { private final Context context; private final WindowManager windowManager; + private final Handler handler = new Handler(); + private LayoutParams windowParams; // Initialized in factory method @@ -100,9 +104,7 @@ public class Bubble { private boolean hideAfterText; private int collapseEndAction; - private final Handler handler = new Handler(); - - private ViewHolder viewHolder; + @VisibleForTesting ViewHolder viewHolder; private ViewPropertyAnimator collapseAnimation; private Integer overrideGravity; private ViewPropertyAnimator exitAnimator; @@ -238,47 +240,22 @@ public class Bubble { updatePrimaryIconAnimation(); } - /** - * Hide the button if visible. Will run a short exit animation before hiding. If the bubble is - * currently showing text, will hide after the text is done displaying. If the bubble is not - * visible this method does nothing. - */ + /** Hide the bubble. */ public void hide() { - if (visibility == Visibility.HIDDEN || visibility == Visibility.EXITING) { - return; - } - - if (textShowing) { - hideAfterText = true; - return; - } - - if (collapseAnimation != null) { - collapseEndAction = CollapseEnd.HIDE; - return; - } - - if (expanded) { - startCollapse(CollapseEnd.HIDE); + if (hideAfterText) { + // hideAndReset() will be called after showing text, do nothing here. return; } + hideHelper(this::defaultAfterHidingAnimation); + } - visibility = Visibility.EXITING; - exitAnimator = - viewHolder - .getPrimaryButton() - .animate() - .setInterpolator(new AnticipateInterpolator()) - .scaleX(0) - .scaleY(0) - .withEndAction( - () -> { - exitAnimator = null; - windowManager.removeView(viewHolder.getRoot()); - visibility = Visibility.HIDDEN; - updatePrimaryIconAnimation(); - }); - exitAnimator.start(); + /** Hide the bubble and reset {@viewHolder} to initial state */ + public void hideAndReset() { + hideHelper( + () -> { + defaultAfterHidingAnimation(); + reset(); + }); } /** Returns whether the bubble is currently visible */ @@ -350,8 +327,15 @@ public class Bubble { public boolean onPreDraw() { primaryButton.getViewTreeObserver().removeOnPreDrawListener(this); - // Prepare and capture end values + // Prepare and capture end values, always use the size of primaryText since + // its invisibility makes primaryButton smaller than expected TransitionValues endValues = new TransitionValues(); + endValues.values.put( + ChangeOnScreenBounds.PROPNAME_WIDTH, + viewHolder.getPrimaryText().getWidth()); + endValues.values.put( + ChangeOnScreenBounds.PROPNAME_HEIGHT, + viewHolder.getPrimaryText().getHeight()); endValues.view = primaryButton; transition.addTarget(endValues.view); transition.captureEndValues(endValues); @@ -377,7 +361,8 @@ public class Bubble { () -> { textShowing = false; if (hideAfterText) { - hide(); + // Always reset here since text shouldn't keep showing. + hideAndReset(); } else { doResize( () -> viewHolder.getPrimaryButton().setDisplayedChild(ViewHolder.CHILD_INDEX_ICON)); @@ -411,6 +396,7 @@ public class Bubble { void primaryButtonClick() { if (expanded || textShowing || currentInfo.getActions().isEmpty()) { + Logger.get(context).logImpression(DialerImpression.Type.BUBBLE_PRIMARY_BUTTON_RETURN_TO_CALL); try { currentInfo.getPrimaryIntent().send(); } catch (CanceledException e) { @@ -419,6 +405,7 @@ public class Bubble { return; } + Logger.get(context).logImpression(DialerImpression.Type.BUBBLE_PRIMARY_BUTTON_EXPAND); doResize( () -> { onLeftRightSwitch(isDrawingFromRight()); @@ -478,6 +465,48 @@ public class Bubble { return viewHolder.getRoot(); } + /** + * Hide the bubble if visible. Will run a short exit animation and before hiding, and {@code + * afterHiding} after hiding. If the bubble is currently showing text, will hide after the text is + * done displaying. If the bubble is not visible this method does nothing. + */ + private void hideHelper(Runnable afterHiding) { + if (visibility == Visibility.HIDDEN || visibility == Visibility.EXITING) { + return; + } + + if (textShowing) { + hideAfterText = true; + return; + } + + if (collapseAnimation != null) { + collapseEndAction = CollapseEnd.HIDE; + return; + } + + if (expanded) { + startCollapse(CollapseEnd.HIDE); + return; + } + + visibility = Visibility.EXITING; + exitAnimator = + viewHolder + .getPrimaryButton() + .animate() + .setInterpolator(new AnticipateInterpolator()) + .scaleX(0) + .scaleY(0) + .withEndAction(afterHiding); + exitAnimator.start(); + } + + private void reset() { + viewHolder = new ViewHolder(viewHolder.getRoot().getContext()); + update(); + } + private void update() { RippleDrawable backgroundRipple = (RippleDrawable) @@ -681,7 +710,16 @@ public class Bubble { windowManager.updateViewLayout(getRootView(), windowParams); } - private class ViewHolder { + private void defaultAfterHidingAnimation() { + exitAnimator = null; + windowManager.removeView(viewHolder.getRoot()); + visibility = Visibility.HIDDEN; + + updatePrimaryIconAnimation(); + } + + @VisibleForTesting + class ViewHolder { public static final int CHILD_INDEX_ICON = 0; public static final int CHILD_INDEX_TEXT = 1; |