Merge "Fixed: Nested shared elements now transition separately." into lmp-mr1-dev

This commit is contained in:
George Mount
2014-10-28 17:00:42 +00:00
committed by Android (Google) Code Review
2 changed files with 102 additions and 44 deletions

View File

@@ -206,6 +206,8 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
private ArrayList<GhostViewListeners> mGhostViewListeners =
new ArrayList<GhostViewListeners>();
private ArrayMap<View, Float> mOriginalAlphas = new ArrayMap<View, Float>();
final private ArrayList<View> mRootSharedElements = new ArrayList<View>();
private ArrayList<Matrix> mSharedElementParentMatrices;
public ActivityTransitionCoordinator(Window window,
ArrayList<String> allSharedElementNames,
@@ -222,15 +224,7 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
if (mListener != null) {
mListener.onMapSharedElements(mAllSharedElementNames, sharedElements);
}
int numSharedElements = sharedElements.size();
for (int i = 0; i < numSharedElements; i++) {
View sharedElement = sharedElements.valueAt(i);
String name = sharedElements.keyAt(i);
if (sharedElement != null && sharedElement.isAttachedToWindow() && name != null) {
mSharedElements.add(sharedElement);
mSharedElementNames.add(name);
}
}
setSharedElements(sharedElements);
if (getViewsTransition() != null && mTransitioningViews != null) {
ViewGroup decorView = getDecor();
if (decorView != null) {
@@ -241,6 +235,58 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
setEpicenter();
}
/**
* Iterates over the shared elements and adds them to the members in order.
* Shared elements that are nested in other shared elements are placed after the
* elements that they are nested in. This means that layout ordering can be done
* from first to last.
*
* @param sharedElements The map of transition names to shared elements to set into
* the member fields.
*/
private void setSharedElements(ArrayMap<String, View> sharedElements) {
boolean isFirstRun = true;
while (!sharedElements.isEmpty()) {
final int numSharedElements = sharedElements.size();
for (int i = numSharedElements - 1; i >= 0; i--) {
final View view = sharedElements.valueAt(i);
final String name = sharedElements.keyAt(i);
if (isFirstRun && (view == null || !view.isAttachedToWindow() || name == null)) {
sharedElements.removeAt(i);
} else {
if (!isNested(view, sharedElements)) {
mSharedElementNames.add(name);
mSharedElements.add(view);
sharedElements.removeAt(i);
if (isFirstRun) {
// We need to keep track which shared elements are roots
// and which are nested.
mRootSharedElements.add(view);
}
}
}
}
isFirstRun = false;
}
}
/**
* Returns true when view is nested in any of the values of sharedElements.
*/
private static boolean isNested(View view, ArrayMap<String, View> sharedElements) {
ViewParent parent = view.getParent();
boolean isNested = false;
while (parent instanceof View) {
View parentView = (View) parent;
if (sharedElements.containsValue(parentView)) {
isNested = true;
break;
}
parent = parentView.getParent();
}
return isNested;
}
protected void stripOffscreenViews() {
if (mTransitioningViews == null) {
return;
@@ -456,11 +502,50 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
view.layout(x, y, x + width, y + height);
}
protected void getSharedElementParentMatrix(View view, Matrix matrix) {
// Find the location in the view's parent
ViewGroup parent = (ViewGroup) view.getParent();
matrix.reset();
parent.transformMatrixToLocal(matrix);
private void setSharedElementMatrices() {
int numSharedElements = mSharedElements.size();
if (numSharedElements > 0) {
mSharedElementParentMatrices = new ArrayList<Matrix>(numSharedElements);
}
for (int i = 0; i < numSharedElements; i++) {
View view = mSharedElements.get(i);
// Find the location in the view's parent
ViewGroup parent = (ViewGroup) view.getParent();
Matrix matrix = new Matrix();
parent.transformMatrixToLocal(matrix);
mSharedElementParentMatrices.add(matrix);
}
}
private void getSharedElementParentMatrix(View view, Matrix matrix) {
final boolean isNestedInOtherSharedElement = !mRootSharedElements.contains(view);
final boolean useParentMatrix;
if (isNestedInOtherSharedElement) {
useParentMatrix = true;
} else {
final int index = mSharedElementParentMatrices == null ? -1
: mSharedElements.indexOf(view);
if (index < 0) {
useParentMatrix = true;
} else {
// The indices of mSharedElementParentMatrices matches the
// mSharedElement matrices.
Matrix parentMatrix = mSharedElementParentMatrices.get(index);
matrix.set(parentMatrix);
useParentMatrix = false;
}
}
if (useParentMatrix) {
matrix.reset();
ViewParent viewParent = view.getParent();
if (viewParent instanceof ViewGroup) {
// Find the location in the view's parent
ViewGroup parent = (ViewGroup) viewParent;
parent.transformMatrixToLocal(matrix);
}
}
}
protected ArrayList<SharedElementOriginalState> setSharedElementState(
@@ -614,6 +699,8 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
mResultReceiver = null;
mPendingTransition = null;
mListener = null;
mRootSharedElements.clear();
mSharedElementParentMatrices = null;
}
protected long getFadeDuration() {
@@ -714,6 +801,7 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
if (!mWindow.getSharedElementsUseOverlay()) {
return;
}
setSharedElementMatrices();
int numSharedElements = mSharedElements.size();
ViewGroup decor = getDecor();
if (decor != null) {

View File

@@ -57,7 +57,6 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
private boolean mIsViewsTransitionStarted;
private boolean mIsViewsTransitionComplete;
private boolean mIsSharedElementTransitionComplete;
private ArrayList<Matrix> mSharedElementParentMatrices;
private Transition mEnterViewsTransition;
public EnterTransitionCoordinator(Activity activity, ResultReceiver resultReceiver,
@@ -122,7 +121,6 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
if (mIsReturning) {
sendSharedElementDestination();
} else {
setSharedElementMatrices();
moveSharedElementsToOverlay();
}
if (mSharedElementsBundle != null) {
@@ -194,7 +192,6 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
}
if (allReady) {
Bundle state = captureSharedElementState();
setSharedElementMatrices();
moveSharedElementsToOverlay();
mResultReceiver.send(MSG_SHARED_ELEMENT_DESTINATION, state);
} else if (decorView != null) {
@@ -205,7 +202,6 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
decorView.getViewTreeObserver().removeOnPreDrawListener(this);
if (mResultReceiver != null) {
Bundle state = captureSharedElementState();
setSharedElementMatrices();
moveSharedElementsToOverlay();
mResultReceiver.send(MSG_SHARED_ELEMENT_DESTINATION, state);
}
@@ -645,30 +641,4 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
});
}
private void setSharedElementMatrices() {
int numSharedElements = mSharedElements.size();
if (numSharedElements > 0) {
mSharedElementParentMatrices = new ArrayList<Matrix>(numSharedElements);
}
for (int i = 0; i < numSharedElements; i++) {
View view = mSharedElements.get(i);
// Find the location in the view's parent
ViewGroup parent = (ViewGroup) view.getParent();
Matrix matrix = new Matrix();
parent.transformMatrixToLocal(matrix);
mSharedElementParentMatrices.add(matrix);
}
}
@Override
protected void getSharedElementParentMatrix(View view, Matrix matrix) {
int index = mSharedElementParentMatrices == null ? -1 : mSharedElements.indexOf(view);
if (index < 0) {
super.getSharedElementParentMatrix(view, matrix);
} else {
matrix.set(mSharedElementParentMatrices.get(index));
}
}
}