am 1bc3c849: Merge "Fix leak in LayoutTransition" into mnc-dev
* commit '1bc3c849ba5e9f23dd7e93012c4b5800b78c221b': Fix leak in LayoutTransition
This commit is contained in:
@@ -28,6 +28,7 @@ import java.util.Collection;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class enables automatic animations on layout changes in ViewGroup objects. To enable
|
* This class enables automatic animations on layout changes in ViewGroup objects. To enable
|
||||||
@@ -757,7 +758,7 @@ public class LayoutTransition {
|
|||||||
// reset the inter-animation delay, in case we use it later
|
// reset the inter-animation delay, in case we use it later
|
||||||
staggerDelay = 0;
|
staggerDelay = 0;
|
||||||
|
|
||||||
final ViewTreeObserver observer = parent.getViewTreeObserver(); // used for later cleanup
|
final ViewTreeObserver observer = parent.getViewTreeObserver();
|
||||||
if (!observer.isAlive()) {
|
if (!observer.isAlive()) {
|
||||||
// If the observer's not in a good state, skip the transition
|
// If the observer's not in a good state, skip the transition
|
||||||
return;
|
return;
|
||||||
@@ -790,21 +791,9 @@ public class LayoutTransition {
|
|||||||
// This is the cleanup step. When we get this rendering event, we know that all of
|
// This is the cleanup step. When we get this rendering event, we know that all of
|
||||||
// the appropriate animations have been set up and run. Now we can clear out the
|
// the appropriate animations have been set up and run. Now we can clear out the
|
||||||
// layout listeners.
|
// layout listeners.
|
||||||
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
|
CleanupCallback callback = new CleanupCallback(layoutChangeListenerMap, parent);
|
||||||
public boolean onPreDraw() {
|
observer.addOnPreDrawListener(callback);
|
||||||
parent.getViewTreeObserver().removeOnPreDrawListener(this);
|
parent.addOnAttachStateChangeListener(callback);
|
||||||
int count = layoutChangeListenerMap.size();
|
|
||||||
if (count > 0) {
|
|
||||||
Collection<View> views = layoutChangeListenerMap.keySet();
|
|
||||||
for (View view : views) {
|
|
||||||
View.OnLayoutChangeListener listener = layoutChangeListenerMap.get(view);
|
|
||||||
view.removeOnLayoutChangeListener(listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
layoutChangeListenerMap.clear();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1499,4 +1488,50 @@ public class LayoutTransition {
|
|||||||
View view, int transitionType);
|
View view, int transitionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class to clean up listeners after animations are setup. Cleanup happens
|
||||||
|
* when either the OnPreDrawListener method is called or when the parent is detached,
|
||||||
|
* whichever comes first.
|
||||||
|
*/
|
||||||
|
private static final class CleanupCallback implements ViewTreeObserver.OnPreDrawListener,
|
||||||
|
View.OnAttachStateChangeListener {
|
||||||
|
|
||||||
|
final Map<View, View.OnLayoutChangeListener> layoutChangeListenerMap;
|
||||||
|
final ViewGroup parent;
|
||||||
|
|
||||||
|
CleanupCallback(Map<View, View.OnLayoutChangeListener> listenerMap, ViewGroup parent) {
|
||||||
|
this.layoutChangeListenerMap = listenerMap;
|
||||||
|
this.parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cleanup() {
|
||||||
|
parent.getViewTreeObserver().removeOnPreDrawListener(this);
|
||||||
|
parent.removeOnAttachStateChangeListener(this);
|
||||||
|
int count = layoutChangeListenerMap.size();
|
||||||
|
if (count > 0) {
|
||||||
|
Collection<View> views = layoutChangeListenerMap.keySet();
|
||||||
|
for (View view : views) {
|
||||||
|
View.OnLayoutChangeListener listener = layoutChangeListenerMap.get(view);
|
||||||
|
view.removeOnLayoutChangeListener(listener);
|
||||||
|
}
|
||||||
|
layoutChangeListenerMap.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewAttachedToWindow(View v) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewDetachedFromWindow(View v) {
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPreDraw() {
|
||||||
|
cleanup();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user