Fix crash in RecyclerView if it's view is animated by Transitions
When it is happening: a) Disappear Visibility transition is applied to the recyclerview(and it's children) b) Transition added the View to the ViewOverlay for an animation c) Transition is first paused before being canceled (for example when the new reversed transition wants to start after user click) d) In Visibility.onPause() we call suppressLayout(false) for RecyclerView e) RecyclerView starts layouting and tries to use our view, but it is currently added to the overlay f) So it crashes on attempt to call addView Fix: Detach a view from overlay in Visibility transition while it is paused. Attach it back in onTransitionResume if the view is still not used by someone else like RecyclerView. Bug: 33609996 Fix in AndroidX: I18d8327b338be442ec30b15fe53a99d1a2974888 Test: cts tests for Transitions Change-Id: I74f138617c8afbac9f6efa4ee9a1f4e961306c9e
This commit is contained in:
@@ -25,6 +25,7 @@ import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewGroupOverlay;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
@@ -413,7 +414,6 @@ public abstract class Visibility extends Transition {
|
||||
}
|
||||
}
|
||||
final int finalVisibility = endVisibility;
|
||||
final ViewGroup finalSceneRoot = sceneRoot;
|
||||
|
||||
if (overlayView != null) {
|
||||
// TODO: Need to do this for general case of adding to overlay
|
||||
@@ -424,16 +424,32 @@ public abstract class Visibility extends Transition {
|
||||
sceneRoot.getLocationOnScreen(loc);
|
||||
overlayView.offsetLeftAndRight((screenX - loc[0]) - overlayView.getLeft());
|
||||
overlayView.offsetTopAndBottom((screenY - loc[1]) - overlayView.getTop());
|
||||
sceneRoot.getOverlay().add(overlayView);
|
||||
final ViewGroupOverlay overlay = sceneRoot.getOverlay();
|
||||
overlay.add(overlayView);
|
||||
Animator animator = onDisappear(sceneRoot, overlayView, startValues, endValues);
|
||||
if (animator == null) {
|
||||
sceneRoot.getOverlay().remove(overlayView);
|
||||
overlay.remove(overlayView);
|
||||
} else {
|
||||
final View finalOverlayView = overlayView;
|
||||
addListener(new TransitionListenerAdapter() {
|
||||
|
||||
@Override
|
||||
public void onTransitionPause(Transition transition) {
|
||||
overlay.remove(finalOverlayView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionResume(Transition transition) {
|
||||
if (finalOverlayView.getParent() == null) {
|
||||
overlay.add(finalOverlayView);
|
||||
} else {
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionEnd(Transition transition) {
|
||||
finalSceneRoot.getOverlay().remove(finalOverlayView);
|
||||
overlay.remove(finalOverlayView);
|
||||
transition.removeListener(this);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user