diff options
Diffstat (limited to 'core/java/android')
-rw-r--r-- | core/java/android/transition/TransitionManager.java | 27 | ||||
-rw-r--r-- | core/java/android/widget/PopupWindow.java | 130 |
2 files changed, 97 insertions, 60 deletions
diff --git a/core/java/android/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java index 7bd6287..80245ef 100644 --- a/core/java/android/transition/TransitionManager.java +++ b/core/java/android/transition/TransitionManager.java @@ -268,7 +268,12 @@ public class TransitionManager { @Override public boolean onPreDraw() { removeListeners(); - sPendingTransitions.remove(mSceneRoot); + + // Don't start the transition if it's no longer pending. + if (!sPendingTransitions.remove(mSceneRoot)) { + return true; + } + // Add to running list, handle end to remove it final ArrayMap<ViewGroup, ArrayList<Transition>> runningTransitions = getRunningTransitions(); @@ -417,4 +422,24 @@ public class TransitionManager { sceneChangeRunTransition(sceneRoot, transitionClone); } } + + /** + * Ends all pending and ongoing transitions on the specified scene root. + * + * @param sceneRoot The root of the View hierarchy to end transitions on. + * @hide + */ + public static void endTransitions(final ViewGroup sceneRoot) { + sPendingTransitions.remove(sceneRoot); + + final ArrayList<Transition> runningTransitions = getRunningTransitions().get(sceneRoot); + if (runningTransitions != null) { + final int count = runningTransitions.size(); + for (int i = 0; i < count; i++) { + final Transition transition = runningTransitions.get(i); + transition.end(); + } + } + + } } diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java index 7cf3eed..2438071 100644 --- a/core/java/android/widget/PopupWindow.java +++ b/core/java/android/widget/PopupWindow.java @@ -1020,23 +1020,24 @@ public class PopupWindow { return; } + TransitionManager.endTransitions(mDecorView); + unregisterForScrollChanged(); mIsShowing = true; mIsDropdown = false; - WindowManager.LayoutParams p = createPopupLayout(token); - p.windowAnimations = computeAnimationResource(); - + final WindowManager.LayoutParams p = createPopupLayoutParams(token); preparePopup(p); - if (gravity == Gravity.NO_GRAVITY) { - gravity = Gravity.TOP | Gravity.START; + + // Only override the default if some gravity was specified. + if (gravity != Gravity.NO_GRAVITY) { + p.gravity = gravity; } - p.gravity = gravity; + p.x = x; p.y = y; - if (mHeightMode < 0) p.height = mLastHeight = mHeightMode; - if (mWidthMode < 0) p.width = mLastWidth = mWidthMode; + invokePopup(p); } @@ -1102,20 +1103,18 @@ public class PopupWindow { return; } + TransitionManager.endTransitions(mDecorView); + registerForScrollChanged(anchor, xoff, yoff, gravity); mIsShowing = true; mIsDropdown = true; - WindowManager.LayoutParams p = createPopupLayout(anchor.getWindowToken()); + final WindowManager.LayoutParams p = createPopupLayoutParams(anchor.getWindowToken()); preparePopup(p); - updateAboveAnchor(findDropDownPosition(anchor, p, xoff, yoff, gravity)); - - if (mHeightMode < 0) p.height = mLastHeight = mHeightMode; - if (mWidthMode < 0) p.width = mLastWidth = mWidthMode; - - p.windowAnimations = computeAnimationResource(); + final boolean aboveAnchor = findDropDownPosition(anchor, p, xoff, yoff, gravity); + updateAboveAnchor(aboveAnchor); invokePopup(p); } @@ -1157,10 +1156,9 @@ public class PopupWindow { } /** - * <p>Prepare the popup by embedding in into a new ViewGroup if the - * background drawable is not null. If embedding is required, the layout - * parameters' height is modified to take into account the background's - * padding.</p> + * Prepare the popup by embedding it into a new ViewGroup if the background + * drawable is not null. If embedding is required, the layout parameters' + * height is modified to take into account the background's padding. * * @param p the layout parameters of the popup's content view */ @@ -1293,26 +1291,39 @@ public class PopupWindow { * * @return the layout parameters to pass to the window manager */ - private WindowManager.LayoutParams createPopupLayout(IBinder token) { - // generates the layout parameters for the drop down - // we want a fixed size view located at the bottom left of the anchor - WindowManager.LayoutParams p = new WindowManager.LayoutParams(); - // these gravity settings put the view at the top left corner of the - // screen. The view is then positioned to the appropriate location - // by setting the x and y offsets to match the anchor's bottom - // left corner + private WindowManager.LayoutParams createPopupLayoutParams(IBinder token) { + final WindowManager.LayoutParams p = new WindowManager.LayoutParams(); + + // These gravity settings put the view at the top left corner of the + // screen. The view is then positioned to the appropriate location by + // setting the x and y offsets to match the anchor's bottom-left + // corner. p.gravity = Gravity.START | Gravity.TOP; - p.width = mLastWidth = mWidth; - p.height = mLastHeight = mHeight; + p.flags = computeFlags(p.flags); + p.type = mWindowLayoutType; + p.token = token; + p.softInputMode = mSoftInputMode; + p.windowAnimations = computeAnimationResource(); + if (mBackground != null) { p.format = mBackground.getOpacity(); } else { p.format = PixelFormat.TRANSLUCENT; } - p.flags = computeFlags(p.flags); - p.type = mWindowLayoutType; - p.token = token; - p.softInputMode = mSoftInputMode; + + if (mHeightMode < 0) { + p.height = mLastHeight = mHeightMode; + } else { + p.height = mLastHeight = mHeight; + } + + if (mWidthMode < 0) { + p.width = mLastWidth = mWidthMode; + } else { + p.width = mLastWidth = mWidth; + } + + // Used for debugging. p.setTitle("PopupWindow:" + Integer.toHexString(hashCode())); return p; @@ -1569,30 +1580,32 @@ public class PopupWindow { * @see #showAsDropDown(android.view.View) */ public void dismiss() { - if (isShowing() && mDecorView != null) { - mIsShowing = false; + if (!isShowing()) { + return; + } - unregisterForScrollChanged(); + unregisterForScrollChanged(); - if (mExitTransition != null) { - mExitTransition.addTarget(mBackgroundView); - mExitTransition.addListener(new Transition.TransitionListenerAdapter() { - @Override - public void onTransitionEnd(Transition transition) { - transition.removeListener(this); - transition.removeTarget(mBackgroundView); + mIsShowing = false; - dismissImmediate(); - } - }); + if (mExitTransition != null) { + mExitTransition.addTarget(mBackgroundView); + mExitTransition.addListener(new Transition.TransitionListenerAdapter() { + @Override + public void onTransitionEnd(Transition transition) { + transition.removeListener(this); + transition.removeTarget(mBackgroundView); - TransitionManager.beginDelayedTransition(mDecorView, mExitTransition); + dismissImmediate(); + } + }); - // Transition to invisible. - mBackgroundView.setVisibility(View.INVISIBLE); - } else { - dismissImmediate(); - } + TransitionManager.beginDelayedTransition(mDecorView, mExitTransition); + + // Transition to invisible. + mBackgroundView.setVisibility(View.INVISIBLE); + } else { + dismissImmediate(); } } @@ -1851,15 +1864,13 @@ public class PopupWindow { } private void unregisterForScrollChanged() { - WeakReference<View> anchorRef = mAnchor; - View anchor = null; - if (anchorRef != null) { - anchor = anchorRef.get(); - } + final WeakReference<View> anchorRef = mAnchor; + final View anchor = anchorRef == null ? null : anchorRef.get(); if (anchor != null) { - ViewTreeObserver vto = anchor.getViewTreeObserver(); + final ViewTreeObserver vto = anchor.getViewTreeObserver(); vto.removeOnScrollChangedListener(mOnScrollChangedListener); } + mAnchor = null; } @@ -1867,7 +1878,8 @@ public class PopupWindow { unregisterForScrollChanged(); mAnchor = new WeakReference<>(anchor); - ViewTreeObserver vto = anchor.getViewTreeObserver(); + + final ViewTreeObserver vto = anchor.getViewTreeObserver(); if (vto != null) { vto.addOnScrollChangedListener(mOnScrollChangedListener); } |