diff options
-rw-r--r-- | api/current.txt | 2 | ||||
-rw-r--r-- | api/system-current.txt | 2 | ||||
-rw-r--r-- | core/java/android/animation/Animator.java | 32 | ||||
-rw-r--r-- | core/java/android/animation/AnimatorInflater.java | 53 | ||||
-rw-r--r-- | core/java/android/view/animation/AnimationUtils.java | 19 |
5 files changed, 78 insertions, 30 deletions
diff --git a/api/current.txt b/api/current.txt index 4a3b3dc..c5d4cdd 100644 --- a/api/current.txt +++ b/api/current.txt @@ -2879,7 +2879,7 @@ package android.animation { method public void removePauseListener(android.animation.Animator.AnimatorPauseListener); method public void resume(); method public abstract android.animation.Animator setDuration(long); - method public void setDurationScaleHint(int, android.content.res.Resources); + method public void setDurationScaleHint(android.content.Context, int); method public abstract void setInterpolator(android.animation.TimeInterpolator); method public abstract void setStartDelay(long); method public void setTarget(java.lang.Object); diff --git a/api/system-current.txt b/api/system-current.txt index 4b283fe..7dcc8ac 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -2959,7 +2959,7 @@ package android.animation { method public void removePauseListener(android.animation.Animator.AnimatorPauseListener); method public void resume(); method public abstract android.animation.Animator setDuration(long); - method public void setDurationScaleHint(int, android.content.res.Resources); + method public void setDurationScaleHint(android.content.Context, int); method public abstract void setInterpolator(android.animation.TimeInterpolator); method public abstract void setStartDelay(long); method public void setTarget(java.lang.Object); diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java index 02a329d..068f700 100644 --- a/core/java/android/animation/Animator.java +++ b/core/java/android/animation/Animator.java @@ -16,6 +16,7 @@ package android.animation; +import android.content.Context; import android.content.res.Configuration; import android.content.res.ConstantState; import android.content.res.Resources; @@ -37,7 +38,7 @@ public abstract class Animator implements Cloneable { public static final int HINT_NO_SCALE = 0; /** - * Set this scale hint (using {@link #setDurationScaleHint(int, Resources)} when the animation's + * Set this scale hint (using {@link #setDurationScaleHint(Context, int)} when the animation's * moving distance is proportional to the screen size. (e.g. a view coming in from the bottom of * the screen to top/center). With this scale hint set, the animation duration will be * automatically scaled based on screen size. @@ -45,7 +46,7 @@ public abstract class Animator implements Cloneable { public static final int HINT_DISTANCE_PROPORTIONAL_TO_SCREEN_SIZE = 1; /** - * Set this scale hint (using {@link #setDurationScaleHint(int, Resources)}) if the animation + * Set this scale hint (using {@link #setDurationScaleHint(Context, int)}) if the animation * has pre-defined moving distance in dp that does not vary from device to device. This is * extremely useful when the animation needs to run on both phones/tablets and TV, because TV * has inflated dp and therefore will have a longer visual arc for the same animation than on @@ -237,12 +238,27 @@ public abstract class Animator implements Cloneable { * users' field of view. Therefore, the duration scale factor is determined by the ratio of the * angular movement on current devices to that on the baseline device (i.e. Nexus 5). * + * @param context Context used to determine the display metrics * @param hint an indicator on how the animation is defined. The hint could be * {@link #HINT_NO_SCALE}, {@link #HINT_DISTANCE_PROPORTIONAL_TO_SCREEN_SIZE} or * {@link #HINT_DISTANCE_DEFINED_IN_DP}. - * @param res The resources {@see android.content.res.Resources} for getting display metrics */ - public void setDurationScaleHint(int hint, Resources res) { + public void setDurationScaleHint(Context context, int hint) { + if (ANIM_DEBUG) { + Log.d("ANIM_DEBUG", "distance based duration hint: " + hint); + } + if (hint == mDurationScaleHint) { + return; + } + if (hint == HINT_NO_SCALE) { + mDurationScaleHint = hint; + return; + } + DisplayMetrics metrics = AnimationUtils.getRealDisplayMetrics(context); + setDurationScaleHint(context.getResources(), metrics, hint); + } + + void setDurationScaleHint(Resources res, DisplayMetrics metrics, int hint) { if (ANIM_DEBUG) { Log.d("ANIM_DEBUG", "distance based duration hint: " + hint); } @@ -252,9 +268,9 @@ public abstract class Animator implements Cloneable { mDurationScaleHint = hint; if (hint != HINT_NO_SCALE) { int uiMode = res.getConfiguration().uiMode & Configuration.UI_MODE_TYPE_MASK; - DisplayMetrics metrics = res.getDisplayMetrics(); - float width = metrics.widthPixels / metrics.xdpi; - float height = metrics.heightPixels / metrics.ydpi; + float dpi = metrics.xdpi; + float width = metrics.widthPixels / dpi; + float height = metrics.heightPixels / dpi; float viewingDistance = AnimationUtils.getViewingDistance(width, height, uiMode); if (ANIM_DEBUG) { Log.d("ANIM_DEBUG", "width, height, viewing distance, uimode: " @@ -263,7 +279,7 @@ public abstract class Animator implements Cloneable { mScreenSizeBasedDurationScale = AnimationUtils .getScreenSizeBasedDurationScale(width, height, viewingDistance); mDpBasedDurationScale = AnimationUtils.getDpBasedDurationScale( - metrics.density, metrics.xdpi, viewingDistance); + metrics.density, dpi, viewingDistance); if (ANIM_DEBUG) { Log.d("ANIM_DEBUG", "screen based scale, dp based scale: " + mScreenSizeBasedDurationScale + ", " + mDpBasedDurationScale); diff --git a/core/java/android/animation/AnimatorInflater.java b/core/java/android/animation/AnimatorInflater.java index 224e8e9..630a2cc 100644 --- a/core/java/android/animation/AnimatorInflater.java +++ b/core/java/android/animation/AnimatorInflater.java @@ -26,6 +26,7 @@ import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.Path; import android.util.AttributeSet; +import android.util.DisplayMetrics; import android.util.Log; import android.util.PathParser; import android.util.StateSet; @@ -85,34 +86,47 @@ public class AnimatorInflater { /** * Loads an {@link Animator} object from a resource * - * @param context Application context used to access resources + * @param context Context used to access resources * @param id The resource id of the animation to load * @return The animator object reference by the specified id * @throws android.content.res.Resources.NotFoundException when the animation cannot be loaded */ public static Animator loadAnimator(Context context, @AnimatorRes int id) throws NotFoundException { - return loadAnimator(context.getResources(), context.getTheme(), id); + return loadAnimator(context, context.getTheme(), id); } /** * Loads an {@link Animator} object from a resource * - * @param resources The resources + * @param context Context used to access resources * @param theme The theme * @param id The resource id of the animation to load * @return The animator object reference by the specified id * @throws android.content.res.Resources.NotFoundException when the animation cannot be loaded * @hide */ - public static Animator loadAnimator(Resources resources, Theme theme, int id) + public static Animator loadAnimator(Context context, Theme theme, int id) throws NotFoundException { - return loadAnimator(resources, theme, id, 1); + return loadAnimator(context, theme, id, 1); } /** @hide */ public static Animator loadAnimator(Resources resources, Theme theme, int id, float pathErrorScale) throws NotFoundException { + DisplayMetrics metrics = resources.getDisplayMetrics(); + return loadAnimator(resources, theme, id, pathErrorScale, metrics); + } + + private static Animator loadAnimator(Context context, Theme theme, int id, float pathErrorScale) + throws NotFoundException { + DisplayMetrics metrics = AnimationUtils.getRealDisplayMetrics(context); + return loadAnimator(context.getResources(), theme, id, pathErrorScale, metrics); + } + + private static Animator loadAnimator(Resources resources, Theme theme, int id, + float pathErrorScale, DisplayMetrics metrics) { + final ConfigurationBoundResourceCache<Animator> animatorCache = resources .getAnimatorCache(); Animator animator = animatorCache.get(id, theme); @@ -127,7 +141,7 @@ public class AnimatorInflater { XmlResourceParser parser = null; try { parser = resources.getAnimation(id); - animator = createAnimatorFromXml(resources, theme, parser, pathErrorScale); + animator = createAnimatorFromXml(resources, theme, parser, pathErrorScale, metrics); if (animator != null) { animator.appendChangingConfigurations(getChangingConfigs(resources, id)); final ConstantState<Animator> constantState = animator.createConstantState(); @@ -239,7 +253,8 @@ public class AnimatorInflater { } if (animator == null) { animator = createAnimatorFromXml(context.getResources(), - context.getTheme(), parser, 1f); + context.getTheme(), parser, 1f, + AnimationUtils.getRealDisplayMetrics(context)); } if (animator == null) { @@ -656,15 +671,15 @@ public class AnimatorInflater { } private static Animator createAnimatorFromXml(Resources res, Theme theme, XmlPullParser parser, - float pixelSize) + float pixelSize, DisplayMetrics metrics) throws XmlPullParserException, IOException { return createAnimatorFromXml(res, theme, parser, Xml.asAttributeSet(parser), null, 0, - pixelSize); + pixelSize, metrics); } private static Animator createAnimatorFromXml(Resources res, Theme theme, XmlPullParser parser, - AttributeSet attrs, AnimatorSet parent, int sequenceOrdering, float pixelSize) - throws XmlPullParserException, IOException { + AttributeSet attrs, AnimatorSet parent, int sequenceOrdering, float pixelSize, + DisplayMetrics metrics) throws XmlPullParserException, IOException { Animator anim = null; ArrayList<Animator> childAnims = null; @@ -683,9 +698,9 @@ public class AnimatorInflater { boolean gotValues = false; if (name.equals("objectAnimator")) { - anim = loadObjectAnimator(res, theme, attrs, pixelSize); + anim = loadObjectAnimator(res, theme, attrs, pixelSize, metrics); } else if (name.equals("animator")) { - anim = loadAnimator(res, theme, attrs, null, pixelSize); + anim = loadAnimator(res, theme, attrs, null, pixelSize, metrics); } else if (name.equals("set")) { anim = new AnimatorSet(); TypedArray a; @@ -697,10 +712,10 @@ public class AnimatorInflater { anim.appendChangingConfigurations(a.getChangingConfigurations()); int ordering = a.getInt(R.styleable.AnimatorSet_ordering, TOGETHER); createAnimatorFromXml(res, theme, parser, attrs, (AnimatorSet) anim, ordering, - pixelSize); + pixelSize, metrics); final int hint = a.getInt(R.styleable.AnimatorSet_durationScaleHint, HINT_NO_SCALE); - anim.setDurationScaleHint(hint, res); + anim.setDurationScaleHint(res, metrics, hint); a.recycle(); } else if (name.equals("propertyValuesHolder")) { PropertyValuesHolder[] values = loadValues(res, theme, parser, @@ -980,10 +995,10 @@ public class AnimatorInflater { } private static ObjectAnimator loadObjectAnimator(Resources res, Theme theme, AttributeSet attrs, - float pathErrorScale) throws NotFoundException { + float pathErrorScale, DisplayMetrics metrics) throws NotFoundException { ObjectAnimator anim = new ObjectAnimator(); - loadAnimator(res, theme, attrs, anim, pathErrorScale); + loadAnimator(res, theme, attrs, anim, pathErrorScale, metrics); return anim; } @@ -998,7 +1013,7 @@ public class AnimatorInflater { * ObjectAnimator */ private static ValueAnimator loadAnimator(Resources res, Theme theme, - AttributeSet attrs, ValueAnimator anim, float pathErrorScale) + AttributeSet attrs, ValueAnimator anim, float pathErrorScale, DisplayMetrics metrics) throws NotFoundException { TypedArray arrayAnimator = null; TypedArray arrayObjectAnimator = null; @@ -1039,7 +1054,7 @@ public class AnimatorInflater { final int hint = arrayAnimator.getInt(R.styleable.Animator_durationScaleHint, HINT_NO_SCALE); - anim.setDurationScaleHint(hint, res); + anim.setDurationScaleHint(res, metrics, hint); arrayAnimator.recycle(); if (arrayObjectAnimator != null) { arrayObjectAnimator.recycle(); diff --git a/core/java/android/view/animation/AnimationUtils.java b/core/java/android/view/animation/AnimationUtils.java index 0417921..4ca4add 100644 --- a/core/java/android/view/animation/AnimationUtils.java +++ b/core/java/android/view/animation/AnimationUtils.java @@ -16,7 +16,10 @@ package android.view.animation; +import android.app.Activity; import android.content.res.Configuration; +import android.util.DisplayMetrics; +import android.view.WindowManager; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -48,7 +51,7 @@ public class AnimationUtils { private static final float RECOMMENDED_FIELD_OF_VIEW_FOR_TV = 40f; private static final float ESTIMATED_VIEWING_DISTANCE_FOR_WATCH = 11f; private static final float AVERAGE_VIEWING_DISTANCE_FOR_PHONES = 14.2f; - private static final float N5_DIAGONAL_VIEW_ANGLE = 19.58f; + private static final float N5_DIAGONAL_VIEW_ANGLE = 19.887228f; private static final float N5_DENSITY = 3.0f; private static final float N5_DPI = 443f; @@ -452,4 +455,18 @@ public class AnimationUtils { AVERAGE_VIEWING_DISTANCE_FOR_PHONES) * 2; return anglePerDp / baselineAnglePerDp; } + + /** + * @hide + */ + public static DisplayMetrics getRealDisplayMetrics(Context context) { + DisplayMetrics metrics = new DisplayMetrics(); + if (context instanceof Activity) { + ((Activity) context).getWindowManager().getDefaultDisplay().getRealMetrics(metrics); + } else { + ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay() + .getRealMetrics(metrics); + } + return metrics; + } } |