summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoris Liu <tianliu@google.com>2015-04-16 18:36:31 -0700
committerDoris Liu <tianliu@google.com>2015-04-17 16:25:01 -0700
commit5ed54c743c04e2bc349e12c31adb67cbc3094651 (patch)
tree4583002203e42ec36612b3e7fcf202dffccb8dc0
parente57818a20e1d21ce705577b670b93d54d2e3a5d3 (diff)
downloadframeworks_base-5ed54c743c04e2bc349e12c31adb67cbc3094651.zip
frameworks_base-5ed54c743c04e2bc349e12c31adb67cbc3094651.tar.gz
frameworks_base-5ed54c743c04e2bc349e12c31adb67cbc3094651.tar.bz2
Use real screen size to scale duration
Duration scale based on screen size was using the area of the screen excluding system bars to compare with our reference device's screen size. This caused the following issues: 1) On baseline device (i.e N5) a scaling factor that is not 1 will be applied to the duration. 2) Scaling on the same device will be different in landscape vs. portrait, as the system bars take different amounts of space in different orienations. This CL fixes both of the above issues. Bug: 20309042 Change-Id: I9d1d0a471d968bee1330b80f0f69a0066d6a1860
-rw-r--r--api/current.txt2
-rw-r--r--api/system-current.txt2
-rw-r--r--core/java/android/animation/Animator.java32
-rw-r--r--core/java/android/animation/AnimatorInflater.java53
-rw-r--r--core/java/android/view/animation/AnimationUtils.java19
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;
+ }
}