From b9f87f029126cd00e1e743cf27d2c2514a475de0 Mon Sep 17 00:00:00 2001 From: keyboardr Date: Wed, 21 Jun 2017 17:59:20 -0700 Subject: Make Bubble's collapseEndAction and visibility states more explicit. This will better handle the cases where a show/hide action is performed while the Bubble is animating. PiperOrigin-RevId: 159771812 Change-Id: I87779da8c0360906587355279b3cc9674289e30f --- java/com/android/dialershared/bubble/Bubble.java | 101 ++++++++++++++------- .../android/dialershared/bubble/MoveHandler.java | 4 +- 2 files changed, 72 insertions(+), 33 deletions(-) (limited to 'java/com/android/dialershared/bubble') diff --git a/java/com/android/dialershared/bubble/Bubble.java b/java/com/android/dialershared/bubble/Bubble.java index b3a49bbd3..f2ba117d8 100644 --- a/java/com/android/dialershared/bubble/Bubble.java +++ b/java/com/android/dialershared/bubble/Bubble.java @@ -19,7 +19,6 @@ package com.android.dialershared.bubble; import android.animation.Animator; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; -import android.animation.PropertyValuesHolder; import android.annotation.SuppressLint; import android.app.PendingIntent.CanceledException; import android.content.Context; @@ -95,16 +94,18 @@ public class Bubble { @NonNull private BubbleInfo currentInfo; - private boolean isShowing; + @Visibility private int visibility; private boolean expanded; private boolean textShowing; private boolean hideAfterText; + private int collapseEndAction; private final Handler handler = new Handler(); private ViewHolder viewHolder; private ViewPropertyAnimator collapseAnimation; private Integer overrideGravity; + private ViewPropertyAnimator exitAnimator; @Retention(RetentionPolicy.SOURCE) @IntDef({CollapseEnd.NOTHING, CollapseEnd.HIDE}) @@ -113,6 +114,15 @@ public class Bubble { int HIDE = 1; } + @Retention(RetentionPolicy.SOURCE) + @IntDef({Visibility.ENTERING, Visibility.SHOWING, Visibility.EXITING, Visibility.HIDDEN}) + private @interface Visibility { + int HIDDEN = 0; + int ENTERING = 1; + int SHOWING = 2; + int EXITING = 3; + } + /** * Determines whether bubbles can be shown based on permissions obtained. This should be checked * before attempting to create a Bubble. @@ -172,7 +182,11 @@ public class Bubble { * already showing this method does nothing. */ public void show() { - if (isShowing) { + if (collapseEndAction == CollapseEnd.HIDE) { + // If show() was called while collapsing, make sure we don't hide after. + collapseEndAction = CollapseEnd.NOTHING; + } + if (visibility == Visibility.SHOWING || visibility == Visibility.ENTERING) { return; } @@ -202,15 +216,25 @@ public class Bubble { windowParams.width = LayoutParams.WRAP_CONTENT; } - windowManager.addView(viewHolder.getRoot(), windowParams); - ObjectAnimator showAnimator = - ObjectAnimator.ofPropertyValuesHolder( - viewHolder.getPrimaryButton(), - PropertyValuesHolder.ofFloat(View.SCALE_X, 0, 1), - PropertyValuesHolder.ofFloat(View.SCALE_Y, 0, 1)); - showAnimator.setInterpolator(new OvershootInterpolator()); - showAnimator.start(); - isShowing = true; + if (exitAnimator != null) { + exitAnimator.cancel(); + exitAnimator = null; + } else { + windowManager.addView(viewHolder.getRoot(), windowParams); + viewHolder.getPrimaryButton().setScaleX(0); + viewHolder.getPrimaryButton().setScaleY(0); + } + + visibility = Visibility.ENTERING; + viewHolder + .getPrimaryButton() + .animate() + .setInterpolator(new OvershootInterpolator()) + .scaleX(1) + .scaleY(1) + .withEndAction(() -> visibility = Visibility.SHOWING) + .start(); + updatePrimaryIconAnimation(); } @@ -220,7 +244,7 @@ public class Bubble { * visible this method does nothing. */ public void hide() { - if (!isShowing) { + if (visibility == Visibility.HIDDEN || visibility == Visibility.EXITING) { return; } @@ -229,29 +253,39 @@ public class Bubble { return; } + if (collapseAnimation != null) { + collapseEndAction = CollapseEnd.HIDE; + return; + } + if (expanded) { startCollapse(CollapseEnd.HIDE); return; } - viewHolder - .getPrimaryButton() - .animate() - .setInterpolator(new AnticipateInterpolator()) - .scaleX(0) - .scaleY(0) - .withEndAction( - () -> { - windowManager.removeView(viewHolder.getRoot()); - isShowing = false; - updatePrimaryIconAnimation(); - }) - .start(); + 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(); } /** Returns whether the bubble is currently visible */ - public boolean isShowing() { - return isShowing; + public boolean isVisible() { + return visibility == Visibility.SHOWING + || visibility == Visibility.ENTERING + || visibility == Visibility.EXITING; } /** @@ -476,7 +510,7 @@ public class Bubble { private void updatePrimaryIconAnimation() { Drawable drawable = viewHolder.getPrimaryIcon().getDrawable(); if (drawable instanceof Animatable) { - if (isShowing) { + if (isVisible()) { ((Animatable) drawable).start(); } else { ((Animatable) drawable).stop(); @@ -581,7 +615,7 @@ public class Bubble { }); } - private void startCollapse(@CollapseEnd int collapseEndAction) { + private void startCollapse(@CollapseEnd int endAction) { View expandedView = viewHolder.getExpandedView(); if (expandedView.getVisibility() != View.VISIBLE || collapseAnimation != null) { // Drawer is already collapsed or animation is running. @@ -590,6 +624,10 @@ public class Bubble { overrideGravity = isDrawingFromRight() ? Gravity.RIGHT : Gravity.LEFT; setFocused(false); + + if (collapseEndAction == CollapseEnd.NOTHING) { + collapseEndAction = endAction; + } collapseAnimation = expandedView .animate() @@ -615,6 +653,7 @@ public class Bubble { if (collapseEndAction == CollapseEnd.HIDE) { hide(); } + collapseEndAction = CollapseEnd.NOTHING; // Resume normal gravity after any resizing is done. handler.postDelayed( @@ -676,7 +715,7 @@ public class Bubble { root.setOnBackPressedListener( () -> { - if (isShowing && expanded) { + if (visibility == Visibility.SHOWING && expanded) { startCollapse(CollapseEnd.NOTHING); return true; } diff --git a/java/com/android/dialershared/bubble/MoveHandler.java b/java/com/android/dialershared/bubble/MoveHandler.java index 9c754dab7..bd8fa1081 100644 --- a/java/com/android/dialershared/bubble/MoveHandler.java +++ b/java/com/android/dialershared/bubble/MoveHandler.java @@ -94,7 +94,7 @@ class MoveHandler implements OnTouchListener { if (wasOnRight != onRight) { bubble.onLeftRightSwitch(onRight); } - if (bubble.isShowing()) { + if (bubble.isVisible()) { windowManager.updateViewLayout(bubble.getRootView(), windowParams); } } @@ -110,7 +110,7 @@ class MoveHandler implements OnTouchListener { @Override public void setValue(LayoutParams object, float value) { object.y = (int) value - bubbleSize - shadowPaddingSize; - if (bubble.isShowing()) { + if (bubble.isVisible()) { windowManager.updateViewLayout(bubble.getRootView(), object); } } -- cgit v1.2.3