diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml index 7e8c9e1eb..26fcbabe7 100644 --- a/samples/ApiDemos/AndroidManifest.xml +++ b/samples/ApiDemos/AndroidManifest.xml @@ -1295,8 +1295,8 @@ + android:enabled="@bool/atLeastHoneycomb" + android:theme="@style/ActivityTransitionTheme"> @@ -1304,9 +1304,9 @@ + android:label="Animation/Activity Transition Details" + android:enabled="@bool/atLeastHoneycomb" + android:theme="@style/ActivityTransitionTheme"> diff --git a/samples/ApiDemos/res/layout/image_block.xml b/samples/ApiDemos/res/layout/image_block.xml index 58d6a23d1..50d7d049e 100644 --- a/samples/ApiDemos/res/layout/image_block.xml +++ b/samples/ApiDemos/res/layout/image_block.xml @@ -1,21 +1,20 @@ \ No newline at end of file diff --git a/samples/ApiDemos/res/layout/image_details.xml b/samples/ApiDemos/res/layout/image_details.xml index e254d640f..a1a745921 100644 --- a/samples/ApiDemos/res/layout/image_details.xml +++ b/samples/ApiDemos/res/layout/image_details.xml @@ -4,22 +4,15 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - android:clipChildren="false" > - - - + sharedElementsMap = new ArrayMap(); - sharedElementsMap.put("hero", mHero.getSharedElementName()); - getWindow().mapTransitionTargets(sharedElementsMap); + @Override + protected void onResume() { + super.onResume(); + if (mComeBack) { + mComeBack = false; + setContentView(R.layout.image_block); } } + private View getHero() { + Bundle transitionArgs = getTransitionArgs(); + if (transitionArgs == null) { + return null; + } + int id = transitionArgs.getInt(KEY_ID); + return findViewById(id); + } + + private static Property DRAWABLE_BOUNDS + = new Property(Rect.class, "bounds") { + @Override + public Rect get(Drawable object) { + return null; + } + + @Override + public void set(Drawable object, Rect value) { + object.setBounds(value); + object.invalidateSelf(); + } + }; + + @Override + public void startSharedElementTransition(Bundle transitionArgs) { + final ImageView hero = (ImageView)getHero(); + hero.setSharedElementName(null); + hero.setVisibility(View.INVISIBLE); + + int[] loc = new int[2]; + hero.getLocationOnScreen(loc); + int endScreenLeft = loc[0]; + int endScreenTop = loc[1]; + int originalWidth = hero.getWidth(); + int originalHeight = hero.getHeight(); + + hero.setVisibility(View.INVISIBLE); + ViewGroup sceneRoot = getContentScene().getSceneRoot(); + sceneRoot.getLocationOnScreen(loc); + int overlayLeft = loc[0]; + int overlayTop = loc[1]; + final ViewGroupOverlay overlay = sceneRoot.getOverlay(); + + int endX = endScreenLeft - overlayLeft; + int endY = endScreenTop - overlayTop; + + int startX = transitionArgs.getInt(KEY_LEFT_ON_SCREEN) - overlayLeft; + int startY = transitionArgs.getInt(KEY_TOP_ON_SCREEN) - overlayTop; + int startWidth = transitionArgs.getInt(KEY_WIDTH); + int startHeight = transitionArgs.getInt(KEY_HEIGHT); + + int endHeight = originalWidth * startHeight / startWidth; + final Drawable image = hero.getDrawable(); + Rect startBounds = new Rect(startX, startY, startX + startWidth, startY + startHeight); + endY += originalHeight - endHeight; + Rect endBounds = new Rect(endX, endY, endX + originalWidth, endY + endHeight); + ObjectAnimator boundsAnimator = ObjectAnimator.ofObject(image, DRAWABLE_BOUNDS, + new RectEvaluator(new Rect()), startBounds, endBounds); + hero.setImageDrawable(null); + image.setBounds(startBounds); + overlay.add(image); + + boundsAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + overlay.remove(image); + hero.setImageDrawable(image); + hero.setVisibility(View.VISIBLE); + } + }); + boundsAnimator.start(); + } + public void clicked(View v) { - mHero = (ImageView) v; + v.setSharedElementName("hero"); + mFall.setHero(v); Intent intent = new Intent(this, ActivityTransitionDetails.class); - intent.putExtra(KEY_ID, v.getId()); - startActivity(intent, new Pair(mHero, "hero")); + Bundle args = getHeroInfo(v); + ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(args); + startActivity(intent, options.toBundle()); + //v.setTranslationZ(300); + mComeBack = true; } private int randomColor() { @@ -90,25 +184,15 @@ public class ActivityTransition extends Activity { return 0xFF000000 | (red << 16) | (green << 8) | blue; } - @Override - public void onCaptureSharedElementStart(Transition transition) { - int width = mHero.getWidth(); - int newTop = mHero.getBottom() - width; - mHero.setTop(newTop); - - int imageWidth = mHero.getDrawable().getIntrinsicWidth(); - mHero.setPivotX(0); - mHero.setPivotY(0); - float scale = ((float)width)/imageWidth; - mHero.setScaleX(scale); - mHero.setScaleY(scale); - } - - @Override - public void onCaptureSharedElementEnd() { - mHero.setPivotX(0); - mHero.setPivotY(0); - mHero.setScaleX(1); - mHero.setScaleY(1); + static Bundle getHeroInfo(View view) { + int[] loc = new int[2]; + view.getLocationOnScreen(loc); + Bundle bundle = new Bundle(); + bundle.putInt(KEY_LEFT_ON_SCREEN, loc[0]); + bundle.putInt(KEY_TOP_ON_SCREEN, loc[1]); + bundle.putInt(KEY_WIDTH, view.getWidth()); + bundle.putInt(KEY_HEIGHT, view.getHeight()); + bundle.putInt(KEY_ID, view.getId()); + return bundle; } } diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/ActivityTransitionDetails.java b/samples/ApiDemos/src/com/example/android/apis/animation/ActivityTransitionDetails.java index 931c5db38..d0b2c4f5a 100644 --- a/samples/ApiDemos/src/com/example/android/apis/animation/ActivityTransitionDetails.java +++ b/samples/ApiDemos/src/com/example/android/apis/animation/ActivityTransitionDetails.java @@ -17,17 +17,26 @@ package com.example.android.apis.animation; import com.example.android.apis.R; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ObjectAnimator; +import android.animation.RectEvaluator; import android.app.Activity; +import android.app.ActivityOptions; import android.content.Intent; +import android.graphics.Matrix; +import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.transition.ChangeBounds; -import android.transition.Transition; import android.transition.TransitionManager; import android.transition.TransitionSet; -import android.util.Pair; +import android.util.Log; +import android.util.Property; import android.view.View; +import android.view.ViewGroup; +import android.view.ViewGroupOverlay; +import android.view.ViewTreeObserver; import android.view.Window; import android.widget.ImageView; @@ -37,94 +46,72 @@ import java.util.Random; * */ public class ActivityTransitionDetails extends Activity { - private static final String TAG = "ActivityTransitionDetails"; + private static final String KEY_LEFT_ON_SCREEN = "ViewTransitionValues:left:"; + private static final String KEY_TOP_ON_SCREEN = "ViewTransitionValues:top:"; + private static final String KEY_WIDTH = "ViewTransitionValues:width:"; + private static final String KEY_HEIGHT = "ViewTransitionValues:height:"; private static final String KEY_ID = "ViewTransitionValues:id"; private Random mRandom = new Random(); - + private boolean mComeBack; private int mImageResourceId = R.drawable.ducky; - - private int mId = R.id.ducky; + private int mId; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_CONTENT_TRANSITIONS); - getWindow().setTriggerEarlyEnterTransition(false); + setEarlyBackgroundTransition(false); getWindow().setBackgroundDrawable(new ColorDrawable(randomColor())); setContentView(R.layout.image_details); - ImageView titleImage = (ImageView) findViewById(R.id.titleImage); - titleImage.setImageDrawable(getHeroDrawable()); - + setImageMatrix(); + ImageView hero = (ImageView)findViewById(R.id.titleImage); + hero.setImageDrawable(getHeroDrawable()); + //hero.setTranslationZ(300); TransitionManager transitionManager = getContentTransitionManager(); TransitionSet transitions = new TransitionSet(); - Fall fall = new Fall(); fall.setDuration(600); + fall.setStartDelay(600); + transitions.addTransition(fall); + transitions.addTransition(new Up()); + transitionManager.setTransition("null", getContentScene(), transitions); + + transitions = new TransitionSet(); + fall = new Fall(); + fall.setDuration(600); transitions.addTransition(fall); transitions.addTransition(new Up()); - transitions.addTransition(new ChangeBounds()); - transitions.addTransition(new ScaleTransition()); - transitionManager.setTransition(getContentScene(), transitions); - transitionManager.setExitTransition(getContentScene(), transitions); + transitionManager.setTransition(getContentScene(), "null", transitions); } @Override - public void onCaptureSharedElementStart(Transition transition) { - ImageView imageView = (ImageView) findViewById(R.id.titleImage); - imageView.setScaleX(1); - imageView.setScaleY(1); - imageView.offsetTopAndBottom(-imageView.getTop()); - } - - @Override - public void onCaptureSharedElementEnd() { - setScale(); - } - - private void setScale() { - ImageView imageView = (ImageView) findViewById(R.id.titleImage); - Drawable drawable = imageView.getDrawable(); - float intrinsicWidth = drawable.getIntrinsicWidth(); - View sharedElementTarget = findViewById(R.id.shared_element); - float scale = sharedElementTarget.getWidth()/intrinsicWidth; - imageView.setPivotY(imageView.getHeight()); - imageView.setScaleX(scale); - imageView.setScaleY(scale); + protected void onResume() { + super.onResume(); + if (mComeBack) { + mComeBack = false; + setContentView(R.layout.image_details); + ImageView hero = (ImageView)findViewById(R.id.titleImage); + hero.setImageDrawable(getHeroDrawable()); + setImageMatrix(); + } } private Drawable getHeroDrawable() { - int id = getIntent().getIntExtra(KEY_ID, mId); - mId = id; - + Bundle args = getTransitionArgs(); + int id = args == null ? 0 : args.getInt(KEY_ID); int resourceId; switch (id) { - case R.id.ducky: - resourceId = R.drawable.ducky; - break; - case R.id.jellies: - resourceId = R.drawable.jellies; - break; - case R.id.mug: - resourceId = R.drawable.mug; - break; - case R.id.pencil: - resourceId = R.drawable.pencil; - break; - case R.id.scissors: - resourceId = R.drawable.scissors; - break; - case R.id.woot: - resourceId = R.drawable.woot; - break; - case R.id.ball: - resourceId = R.drawable.ball; - break; - case R.id.block: - resourceId = R.drawable.block; - break; + case R.id.ducky: resourceId = R.drawable.ducky; break; + case R.id.jellies: resourceId = R.drawable.jellies; break; + case R.id.mug: resourceId = R.drawable.mug; break; + case R.id.pencil: resourceId = R.drawable.pencil; break; + case R.id.scissors: resourceId = R.drawable.scissors; break; + case R.id.woot: resourceId = R.drawable.woot; break; + case R.id.ball: resourceId = R.drawable.ball; break; + case R.id.block: resourceId = R.drawable.block; break; default: resourceId = mImageResourceId; break; @@ -133,10 +120,96 @@ public class ActivityTransitionDetails extends Activity { return getResources().getDrawable(resourceId); } + private static Property DRAWABLE_BOUNDS + = new Property(Rect.class, "bounds") { + @Override + public Rect get(Drawable object) { + return null; + } + + @Override + public void set(Drawable object, Rect value) { + object.setBounds(value); + object.invalidateSelf(); + } + }; + + private void setImageMatrix() { + getWindow().getDecorView().getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { + @Override + public boolean onPreDraw() { + getWindow().getDecorView().getViewTreeObserver().removeOnPreDrawListener(this); + // Use an image matrix such that it aligns with the bottom. + final ImageView hero = (ImageView)findViewById(R.id.titleImage); + hero.setScaleType(ImageView.ScaleType.MATRIX); + Matrix matrix = hero.getImageMatrix(); + int height = hero.getHeight(); + int width = hero.getWidth(); + Drawable image = hero.getDrawable(); + int intrinsicHeight = image.getIntrinsicHeight(); + int intrinsicWidth = image.getIntrinsicWidth(); + int scaledHeight = intrinsicHeight * width / intrinsicWidth; + matrix.postTranslate(0, (height - scaledHeight) / 2); + hero.setImageMatrix(matrix); + return true; + } + }); + } + + @Override + public void startSharedElementTransition(Bundle transitionArgs) { + mId = transitionArgs.getInt(KEY_ID); + final ImageView hero = (ImageView)findViewById(R.id.titleImage); + int[] loc = new int[2]; + hero.getLocationOnScreen(loc); + int endScreenLeft = loc[0]; + int endScreenTop = loc[1]; + int originalWidth = hero.getWidth(); + int originalHeight = hero.getHeight(); + + hero.setVisibility(View.INVISIBLE); + ViewGroup sceneRoot = getContentScene().getSceneRoot(); + sceneRoot.getLocationOnScreen(loc); + int overlayLeft = loc[0]; + int overlayTop = loc[1]; + final ViewGroupOverlay overlay = sceneRoot.getOverlay(); + + int endX = endScreenLeft - overlayLeft; + int endY = endScreenTop - overlayTop; + + int startX = transitionArgs.getInt(KEY_LEFT_ON_SCREEN) - overlayLeft; + int startY = transitionArgs.getInt(KEY_TOP_ON_SCREEN) - overlayTop; + int startWidth = transitionArgs.getInt(KEY_WIDTH); + int startHeight = transitionArgs.getInt(KEY_HEIGHT); + + int endHeight = originalWidth * startHeight / startWidth; + final Drawable image = hero.getDrawable(); + Rect startBounds = new Rect(startX, startY, startX + startWidth, startY + startHeight); + endY += originalHeight - endHeight; + Rect endBounds = new Rect(endX, endY, endX + originalWidth, endY + endHeight); + ObjectAnimator boundsAnimator = ObjectAnimator.ofObject(image, DRAWABLE_BOUNDS, + new RectEvaluator(new Rect()), startBounds, endBounds); + hero.setImageDrawable(null); + image.setBounds(startBounds); + overlay.add(image); + + boundsAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + overlay.remove(image); + hero.setImageDrawable(image); + hero.setVisibility(View.VISIBLE); + } + }); + boundsAnimator.start(); + } + public void clicked(View v) { Intent intent = new Intent(this, ActivityTransition.class); - intent.putExtra(KEY_ID, mId); - startActivity(intent, new Pair(v, "hero")); + Bundle args = getHeroInfo((ImageView)v); + ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(args); + startActivity(intent, options.toBundle()); + mComeBack = true; } private int randomColor() { @@ -146,4 +219,22 @@ public class ActivityTransitionDetails extends Activity { return 0xFF000000 | (red << 16) | (green << 8) | blue; } + private Bundle getHeroInfo(ImageView view) { + int[] loc = new int[2]; + view.getLocationOnScreen(loc); + Bundle bundle = new Bundle(); + Drawable image = view.getDrawable(); + int intrinsicWidth = image.getIntrinsicWidth(); + int intrinsicHeight = image.getIntrinsicHeight(); + int width = view.getWidth(); + int height = intrinsicHeight * width / intrinsicWidth; + int top = loc[1] + view.getHeight() - height; + bundle.putInt(KEY_LEFT_ON_SCREEN, loc[0]); + bundle.putInt(KEY_TOP_ON_SCREEN, top); + bundle.putInt(KEY_WIDTH, width); + bundle.putInt(KEY_HEIGHT, height); + bundle.putInt(KEY_ID, mId); + return bundle; + } + } diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/Fall.java b/samples/ApiDemos/src/com/example/android/apis/animation/Fall.java index 6a866e572..e7281b383 100644 --- a/samples/ApiDemos/src/com/example/android/apis/animation/Fall.java +++ b/samples/ApiDemos/src/com/example/android/apis/animation/Fall.java @@ -20,9 +20,11 @@ import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.TimeInterpolator; +import android.animation.ValueAnimator; import android.transition.Transition; import android.transition.TransitionValues; import android.transition.Visibility; +import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.view.animation.AccelerateInterpolator; @@ -37,7 +39,11 @@ public class Fall extends Visibility { private static final String TAG = "Fall"; private static final String PROPNAME_SCREEN_LOCATION = "android:fade:screen_location"; - private View mFocusElement; + private View mHero; + + public void setHero(View hero) { + mHero = hero; + } private Animator createAnimation(final View view, long startDelay, final float startY, float endY, AnimatorListenerAdapter listener, TimeInterpolator interpolator) { @@ -93,6 +99,7 @@ public class Fall extends Visibility { return null; } final View endView = endValues.view; + Log.v(TAG, "onAppear: " + endView.getId()); final float endY = endView.getTranslationY(); final float startY = endY + sceneRoot.getHeight(); @@ -129,9 +136,8 @@ public class Fall extends Visibility { } }; addListener(transitionListener); - View sharedElement = getFocusElement(sceneRoot); int[] loc = (int[]) endValues.values.get(PROPNAME_SCREEN_LOCATION); - long startDelay = calculateRiseStartDelay(sceneRoot, sharedElement, endView, loc); + long startDelay = calculateRiseStartDelay(sceneRoot, endView, loc); return createAnimation(endView, startDelay, startY, endY, null, sDecelerate); } @@ -184,13 +190,12 @@ public class Fall extends Visibility { } } final int finalVisibility = endVisibility; - View sharedElement = getFocusElement(sceneRoot); int[] loc = (int[]) startValues.values.get(PROPNAME_SCREEN_LOCATION); // TODO: add automatic facility to Visibility superclass for keeping views around if (overlayView != null) { // TODO: Need to do this for general case of adding to overlay - long startDelay = calculateFallStartDelay(sceneRoot, sharedElement, overlayView, loc); + long startDelay = calculateFallStartDelay(sceneRoot, overlayView, loc); int screenX = loc[0]; int screenY = loc[1]; loc = new int[2]; @@ -235,7 +240,7 @@ public class Fall extends Visibility { return createAnimation(view, startDelay, startY, endY, endListener, sAccelerate); } if (viewToKeep != null) { - long startDelay = calculateFallStartDelay(sceneRoot, sharedElement, viewToKeep, loc); + long startDelay = calculateFallStartDelay(sceneRoot, viewToKeep, loc); // TODO: find a different way to do this, like just changing the view to be // VISIBLE for the duration of the transition viewToKeep.setVisibility((View.VISIBLE)); @@ -294,73 +299,37 @@ public class Fall extends Visibility { return null; } - private View getFocusElement(ViewGroup sceneRoot) { - if (mFocusElement == null) { - mFocusElement = findFocusElement(sceneRoot); - if (mFocusElement == null) { - mFocusElement = sceneRoot; - } - } - return (mFocusElement == sceneRoot) ? null : mFocusElement; - } - - private static View findFocusElement(ViewGroup viewGroup) { - int numChildren = viewGroup.getChildCount(); - for (int i = 0; i < numChildren; i++) { - View child = viewGroup.getChildAt(i); - String sharedElementName = child.getSharedElementName(); - if (sharedElementName != null && !sharedElementName.startsWith("android:")) { - return child; - } - if (child instanceof ViewGroup) { - View sharedElement = findFocusElement((ViewGroup) child); - if (sharedElement != null) { - return sharedElement; - } - } - } - return null; - } - - private long calculateFallStartDelay(ViewGroup sceneRoot, View shared, View view, - int[] viewLoc) { + private long calculateFallStartDelay(View sceneRoot, View view, int[] viewLoc) { int[] loc = new int[2]; sceneRoot.getLocationOnScreen(loc); int bottom = loc[1] + sceneRoot.getHeight(); float distance = bottom - viewLoc[1] + view.getTranslationY(); - if (shared != null) { - shared.getLocationOnScreen(loc); - float heroX = loc[0] + shared.getTranslationX() + (shared.getWidth() / 2.0f); + if (mHero != null) { + mHero.getLocationOnScreen(loc); + float heroX = loc[0] + mHero.getTranslationX() + (mHero.getWidth() / 2.0f); float viewX = viewLoc[0] + view.getTranslationX() + (view.getWidth() / 2.0f); float distanceX = Math.abs(heroX - viewX); float distanceXRatio = distanceX / sceneRoot.getWidth(); - distance += (1 - distanceXRatio) * shared.getHeight(); + distance += (1 - distanceXRatio) * mHero.getHeight(); } float distanceRatio = distance/sceneRoot.getHeight() / 3; return Math.max(0, Math.round(distanceRatio * getDuration())); } - private long calculateRiseStartDelay(View sceneRoot, View shared, View view, int[] viewLoc) { + private long calculateRiseStartDelay(View sceneRoot, View view, int[] viewLoc) { int[] loc = new int[2]; sceneRoot.getLocationOnScreen(loc); int top = loc[1]; float distance = viewLoc[1] + view.getTranslationY() - top; - if (shared != null) { - shared.getLocationOnScreen(loc); - float heroX = loc[0] + shared.getTranslationX() + (shared.getWidth() / 2.0f); + if (mHero != null) { + mHero.getLocationOnScreen(loc); + float heroX = loc[0] + mHero.getTranslationX() + (mHero.getWidth() / 2.0f); float viewX = viewLoc[0] + view.getTranslationX() + (view.getWidth() / 2.0f); float distanceX = Math.abs(heroX - viewX); float distanceXRatio = distanceX / sceneRoot.getWidth(); - distance += distanceXRatio * shared.getHeight(); + distance += distanceXRatio * mHero.getHeight(); } float distanceRatio = distance/sceneRoot.getHeight() / 3; return Math.max(0, Math.round(distanceRatio * getDuration())); } - - @Override - public Transition clone() { - Fall transition = (Fall) super.clone(); - transition.mFocusElement = null; - return transition; - } } diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/ScaleTransition.java b/samples/ApiDemos/src/com/example/android/apis/animation/ScaleTransition.java deleted file mode 100644 index 787cdb374..000000000 --- a/samples/ApiDemos/src/com/example/android/apis/animation/ScaleTransition.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.example.android.apis.animation; - -import android.animation.Animator; -import android.animation.AnimatorSet; -import android.animation.ObjectAnimator; -import android.transition.Transition; -import android.transition.TransitionValues; -import android.util.Property; -import android.view.View; -import android.view.ViewGroup; - -/** - * - */ -public class ScaleTransition extends Transition { - private static final String PROPNAME_SCALE_X = "android:scale:x"; - private static final String PROPNAME_SCALE_Y = "android:scale:y"; - private static final String[] sTransitionProperties = { - PROPNAME_SCALE_X, - PROPNAME_SCALE_Y, - }; - - @Override - public String[] getTransitionProperties() { - return sTransitionProperties; - } - - @Override - public void captureStartValues(TransitionValues transitionValues) { - captureValues(transitionValues); - } - - @Override - public void captureEndValues(TransitionValues transitionValues) { - captureValues(transitionValues); - } - - private void captureValues(TransitionValues transitionValues) { - transitionValues.values.put(PROPNAME_SCALE_X, transitionValues.view.getScaleX()); - transitionValues.values.put(PROPNAME_SCALE_Y, transitionValues.view.getScaleY()); - } - - @Override - public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, - TransitionValues endValues) { - if (startValues == null || endValues == null) { - return null; - } - Animator scaleXAnimator = createScaleAnimator(startValues, endValues, PROPNAME_SCALE_X, - View.SCALE_X); - Animator scaleYAnimator = createScaleAnimator(startValues, endValues, PROPNAME_SCALE_Y, - View.SCALE_Y); - if (scaleXAnimator == null) { - return scaleYAnimator; - } else if (scaleYAnimator == null) { - return scaleXAnimator; - } - AnimatorSet animatorSet = new AnimatorSet(); - animatorSet.playTogether(scaleXAnimator, scaleYAnimator); - return animatorSet; - } - - private Animator createScaleAnimator(TransitionValues startValues, TransitionValues endValues, - String propertyName, Property scaleProperty) { - float start = (Float)startValues.values.get(propertyName); - float end = (Float)endValues.values.get(propertyName); - if (start == end) { - return null; - } - return ObjectAnimator.ofFloat(endValues.view, scaleProperty, start, end); - } -}