am c9d8e383: Merge "Fix leak with transitions when views get removed" into klp-dev
* commit 'c9d8e38317947c7860dcf6e8df032373ace183e9': Fix leak with transitions when views get removed
This commit is contained in:
@@ -994,15 +994,7 @@ public abstract class Transition implements Cloneable {
|
||||
* false otherwise
|
||||
*/
|
||||
void captureValues(ViewGroup sceneRoot, boolean start) {
|
||||
if (start) {
|
||||
mStartValues.viewValues.clear();
|
||||
mStartValues.idValues.clear();
|
||||
mStartValues.itemIdValues.clear();
|
||||
} else {
|
||||
mEndValues.viewValues.clear();
|
||||
mEndValues.idValues.clear();
|
||||
mEndValues.itemIdValues.clear();
|
||||
}
|
||||
clearValues(start);
|
||||
if (mTargetIds.size() > 0 || mTargets.size() > 0) {
|
||||
if (mTargetIds.size() > 0) {
|
||||
for (int i = 0; i < mTargetIds.size(); ++i) {
|
||||
@@ -1054,6 +1046,23 @@ public abstract class Transition implements Cloneable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear valuesMaps for specified start/end state
|
||||
*
|
||||
* @param start true if the start values should be cleared, false otherwise
|
||||
*/
|
||||
void clearValues(boolean start) {
|
||||
if (start) {
|
||||
mStartValues.viewValues.clear();
|
||||
mStartValues.idValues.clear();
|
||||
mStartValues.itemIdValues.clear();
|
||||
} else {
|
||||
mEndValues.viewValues.clear();
|
||||
mEndValues.idValues.clear();
|
||||
mEndValues.itemIdValues.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive method which captures values for an entire view hierarchy,
|
||||
* starting at some root view. Transitions without targetIDs will use this
|
||||
|
||||
@@ -19,6 +19,7 @@ package android.transition;
|
||||
import android.content.Context;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
|
||||
@@ -205,48 +206,91 @@ public class TransitionManager {
|
||||
|
||||
private static void sceneChangeRunTransition(final ViewGroup sceneRoot,
|
||||
final Transition transition) {
|
||||
if (transition != null) {
|
||||
final ViewTreeObserver observer = sceneRoot.getViewTreeObserver();
|
||||
final ViewTreeObserver.OnPreDrawListener listener =
|
||||
new ViewTreeObserver.OnPreDrawListener() {
|
||||
public boolean onPreDraw() {
|
||||
sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
|
||||
sPendingTransitions.remove(sceneRoot);
|
||||
// Add to running list, handle end to remove it
|
||||
final ArrayMap<ViewGroup, ArrayList<Transition>> runningTransitions =
|
||||
getRunningTransitions();
|
||||
ArrayList<Transition> currentTransitions = runningTransitions.get(sceneRoot);
|
||||
ArrayList<Transition> previousRunningTransitions = null;
|
||||
if (currentTransitions == null) {
|
||||
currentTransitions = new ArrayList<Transition>();
|
||||
runningTransitions.put(sceneRoot, currentTransitions);
|
||||
} else if (currentTransitions.size() > 0) {
|
||||
previousRunningTransitions = new ArrayList<Transition>(currentTransitions);
|
||||
}
|
||||
currentTransitions.add(transition);
|
||||
transition.addListener(new Transition.TransitionListenerAdapter() {
|
||||
@Override
|
||||
public void onTransitionEnd(Transition transition) {
|
||||
ArrayList<Transition> currentTransitions =
|
||||
runningTransitions.get(sceneRoot);
|
||||
currentTransitions.remove(transition);
|
||||
}
|
||||
});
|
||||
transition.captureValues(sceneRoot, false);
|
||||
if (previousRunningTransitions != null) {
|
||||
for (Transition runningTransition : previousRunningTransitions) {
|
||||
runningTransition.resume();
|
||||
}
|
||||
}
|
||||
transition.playTransition(sceneRoot);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
observer.addOnPreDrawListener(listener);
|
||||
if (transition != null && sceneRoot != null) {
|
||||
MultiListener listener = new MultiListener(transition, sceneRoot);
|
||||
sceneRoot.addOnAttachStateChangeListener(listener);
|
||||
sceneRoot.getViewTreeObserver().addOnPreDrawListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This private utility class is used to listen for both OnPreDraw and
|
||||
* OnAttachStateChange events. OnPreDraw events are the main ones we care
|
||||
* about since that's what triggers the transition to take place.
|
||||
* OnAttachStateChange events are also important in case the view is removed
|
||||
* from the hierarchy before the OnPreDraw event takes place; it's used to
|
||||
* clean up things since the OnPreDraw listener didn't get called in time.
|
||||
*/
|
||||
private static class MultiListener implements ViewTreeObserver.OnPreDrawListener,
|
||||
View.OnAttachStateChangeListener {
|
||||
|
||||
Transition mTransition;
|
||||
ViewGroup mSceneRoot;
|
||||
|
||||
MultiListener(Transition transition, ViewGroup sceneRoot) {
|
||||
mTransition = transition;
|
||||
mSceneRoot = sceneRoot;
|
||||
}
|
||||
|
||||
private void removeListeners() {
|
||||
mSceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
|
||||
mSceneRoot.removeOnAttachStateChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewAttachedToWindow(View v) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewDetachedFromWindow(View v) {
|
||||
removeListeners();
|
||||
|
||||
sPendingTransitions.remove(mSceneRoot);
|
||||
ArrayList<Transition> runningTransitions = getRunningTransitions().get(mSceneRoot);
|
||||
if (runningTransitions != null && runningTransitions.size() > 0) {
|
||||
for (Transition runningTransition : runningTransitions) {
|
||||
runningTransition.resume();
|
||||
}
|
||||
}
|
||||
mTransition.clearValues(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreDraw() {
|
||||
removeListeners();
|
||||
sPendingTransitions.remove(mSceneRoot);
|
||||
// Add to running list, handle end to remove it
|
||||
final ArrayMap<ViewGroup, ArrayList<Transition>> runningTransitions =
|
||||
getRunningTransitions();
|
||||
ArrayList<Transition> currentTransitions = runningTransitions.get(mSceneRoot);
|
||||
ArrayList<Transition> previousRunningTransitions = null;
|
||||
if (currentTransitions == null) {
|
||||
currentTransitions = new ArrayList<Transition>();
|
||||
runningTransitions.put(mSceneRoot, currentTransitions);
|
||||
} else if (currentTransitions.size() > 0) {
|
||||
previousRunningTransitions = new ArrayList<Transition>(currentTransitions);
|
||||
}
|
||||
currentTransitions.add(mTransition);
|
||||
mTransition.addListener(new Transition.TransitionListenerAdapter() {
|
||||
@Override
|
||||
public void onTransitionEnd(Transition transition) {
|
||||
ArrayList<Transition> currentTransitions =
|
||||
runningTransitions.get(mSceneRoot);
|
||||
currentTransitions.remove(transition);
|
||||
}
|
||||
});
|
||||
mTransition.captureValues(mSceneRoot, false);
|
||||
if (previousRunningTransitions != null) {
|
||||
for (Transition runningTransition : previousRunningTransitions) {
|
||||
runningTransition.resume();
|
||||
}
|
||||
}
|
||||
mTransition.playTransition(mSceneRoot);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
private static void sceneChangeSetup(ViewGroup sceneRoot, Transition transition) {
|
||||
|
||||
// Capture current values
|
||||
|
||||
@@ -65,7 +65,7 @@ public class KeyguardTransportControlView extends FrameLayout {
|
||||
protected static final boolean DEBUG = false;
|
||||
protected static final String TAG = "TransportControlView";
|
||||
|
||||
private static final boolean ANIMATE_TRANSITIONS = false;
|
||||
private static final boolean ANIMATE_TRANSITIONS = true;
|
||||
|
||||
private ViewGroup mMetadataContainer;
|
||||
private ViewGroup mInfoContainer;
|
||||
|
||||
Reference in New Issue
Block a user