From 153e4c9018d66554e50f3956864045677e3ef164 Mon Sep 17 00:00:00 2001 From: keyboardr Date: Tue, 20 Jun 2017 14:28:02 -0700 Subject: Properly handle configuration changes in Bubble The WindowRoot now provides a listener for when the Configuration state changes. Bubble will then reinitialize the MoveHandler (to account for potential changes in screen bounds) and ensure the window is within bounds. PiperOrigin-RevId: 159614123 Change-Id: Icace5b52299825836fb398ce1e6234ad0bb212f3 --- java/com/android/dialershared/bubble/Bubble.java | 9 +++++- .../android/dialershared/bubble/MoveHandler.java | 32 +++++++++++++++------- .../android/dialershared/bubble/WindowRoot.java | 27 +++++++++++++++--- 3 files changed, 53 insertions(+), 15 deletions(-) (limited to 'java/com/android/dialershared') diff --git a/java/com/android/dialershared/bubble/Bubble.java b/java/com/android/dialershared/bubble/Bubble.java index dbb5ea759..b3a49bbd3 100644 --- a/java/com/android/dialershared/bubble/Bubble.java +++ b/java/com/android/dialershared/bubble/Bubble.java @@ -647,7 +647,7 @@ public class Bubble { public static final int CHILD_INDEX_ICON = 0; public static final int CHILD_INDEX_TEXT = 1; - private final MoveHandler moveHandler; + private MoveHandler moveHandler; private final WindowRoot root; private final ViewAnimator primaryButton; private final ImageView primaryIcon; @@ -682,6 +682,13 @@ public class Bubble { } return false; }); + root.setOnConfigurationChangedListener( + (configuration) -> { + // The values in the current MoveHandler may be stale, so replace it. Then ensure the + // Window is in bounds + moveHandler = new MoveHandler(primaryButton, Bubble.this); + moveHandler.snapToBounds(); + }); root.setOnTouchListener( (v, event) -> { if (expanded && event.getActionMasked() == MotionEvent.ACTION_OUTSIDE) { diff --git a/java/com/android/dialershared/bubble/MoveHandler.java b/java/com/android/dialershared/bubble/MoveHandler.java index bc6db64bc..9c754dab7 100644 --- a/java/com/android/dialershared/bubble/MoveHandler.java +++ b/java/com/android/dialershared/bubble/MoveHandler.java @@ -149,6 +149,13 @@ class MoveHandler implements OnTouchListener { xProperty.setValue(windowParams, xProperty.getValue(windowParams)); } + public void snapToBounds() { + ensureSprings(); + + moveXAnimation.animateToFinalPosition(relativeToRight(bubble.getWindowParams()) ? maxX : minX); + moveYAnimation.animateToFinalPosition(yProperty.getValue(bubble.getWindowParams())); + } + @Override public boolean onTouch(View v, MotionEvent event) { float eventX = event.getRawX(); @@ -166,16 +173,7 @@ class MoveHandler implements OnTouchListener { bubble.onMoveStart(); } - if (moveXAnimation == null) { - moveXAnimation = new SpringAnimation(bubble.getWindowParams(), xProperty); - moveXAnimation.setSpring(new SpringForce()); - moveXAnimation.getSpring().setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY); - } - if (moveYAnimation == null) { - moveYAnimation = new SpringAnimation(bubble.getWindowParams(), yProperty); - moveYAnimation.setSpring(new SpringForce()); - moveYAnimation.getSpring().setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY); - } + ensureSprings(); moveXAnimation.animateToFinalPosition(MathUtils.clamp(eventX, minX, maxX)); moveYAnimation.animateToFinalPosition(MathUtils.clamp(eventY, minY, maxY)); @@ -216,6 +214,20 @@ class MoveHandler implements OnTouchListener { return true; } + private void ensureSprings() { + if (moveXAnimation == null) { + moveXAnimation = new SpringAnimation(bubble.getWindowParams(), xProperty); + moveXAnimation.setSpring(new SpringForce()); + moveXAnimation.getSpring().setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY); + } + + if (moveYAnimation == null) { + moveYAnimation = new SpringAnimation(bubble.getWindowParams(), yProperty); + moveYAnimation.setSpring(new SpringForce()); + moveYAnimation.getSpring().setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY); + } + } + private Point findTarget(float xVelocity, float yVelocity, int startX, int startY) { if (scroller == null) { scroller = new Scroller(context); diff --git a/java/com/android/dialershared/bubble/WindowRoot.java b/java/com/android/dialershared/bubble/WindowRoot.java index 2c176662e..81d6b487b 100644 --- a/java/com/android/dialershared/bubble/WindowRoot.java +++ b/java/com/android/dialershared/bubble/WindowRoot.java @@ -17,23 +17,30 @@ package com.android.dialershared.bubble; import android.content.Context; +import android.content.res.Configuration; import android.support.annotation.NonNull; import android.view.KeyEvent; import android.widget.FrameLayout; /** - * ViewGroup that handles some overlay window concerns. Allows back button events to be listened for - * via an interface. + * ViewGroup that handles some overlay window concerns. Allows back button and configuration change + * events to be listened for via interfaces. */ public class WindowRoot extends FrameLayout { - private OnBackPressedListener backPressedListener; - /** Callback for when the back button is pressed while this window is in focus */ public interface OnBackPressedListener { boolean onBackPressed(); } + /** Callback for when the Configuration changes for this window */ + public interface OnConfigurationChangedListener { + void onConfigurationChanged(Configuration newConfiguration); + } + + private OnBackPressedListener backPressedListener; + private OnConfigurationChangedListener configurationChangedListener; + public WindowRoot(@NonNull Context context) { super(context); } @@ -42,6 +49,10 @@ public class WindowRoot extends FrameLayout { backPressedListener = listener; } + public void setOnConfigurationChangedListener(OnConfigurationChangedListener listener) { + configurationChangedListener = listener; + } + @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && backPressedListener != null) { @@ -52,4 +63,12 @@ public class WindowRoot extends FrameLayout { } return super.dispatchKeyEvent(event); } + + @Override + public void dispatchConfigurationChanged(Configuration newConfig) { + super.dispatchConfigurationChanged(newConfig); + if (configurationChangedListener != null) { + configurationChangedListener.onConfigurationChanged(newConfig); + } + } } -- cgit v1.2.3