Merge "Resize the VectorDrawable according to the virtual Dpi" into mnc-dev

This commit is contained in:
ztenghui
2015-06-24 23:32:16 +00:00
committed by Android (Google) Code Review
2 changed files with 76 additions and 12 deletions

View File

@@ -170,7 +170,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
public Drawable mutate() { public Drawable mutate() {
if (!mMutated && super.mutate() == this) { if (!mMutated && super.mutate() == this) {
mAnimatedVectorState = new AnimatedVectorDrawableState( mAnimatedVectorState = new AnimatedVectorDrawableState(
mAnimatedVectorState, mCallback, null); mAnimatedVectorState, mCallback, mRes);
mMutated = true; mMutated = true;
} }
return this; return this;

View File

@@ -15,6 +15,7 @@
package android.graphics.drawable; package android.graphics.drawable;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.content.res.Resources; import android.content.res.Resources;
import android.content.res.Resources.Theme; import android.content.res.Resources.Theme;
@@ -31,10 +32,10 @@ import android.graphics.PathMeasure;
import android.graphics.PixelFormat; import android.graphics.PixelFormat;
import android.graphics.PorterDuffColorFilter; import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuff.Mode;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.LayoutDirection; import android.util.LayoutDirection;
import android.util.Log; import android.util.Log;
import android.util.MathUtils; import android.util.MathUtils;
@@ -212,13 +213,24 @@ public class VectorDrawable extends Drawable {
// caching the bitmap by default is allowed. // caching the bitmap by default is allowed.
private boolean mAllowCaching = true; private boolean mAllowCaching = true;
// Given the virtual display setup, the dpi can be different than the inflation's dpi.
// Therefore, we need to scale the values we got from the getDimension*().
private int mDpiScaledWidth = 0;
private int mDpiScaledHeight = 0;
private Insets mDpiScaleInsets = Insets.NONE;
public VectorDrawable() { public VectorDrawable() {
mVectorState = new VectorDrawableState(); this(null, null);
} }
private VectorDrawable(@NonNull VectorDrawableState state) { private VectorDrawable(@NonNull VectorDrawableState state, @Nullable Resources res) {
mVectorState = state; if (state == null) {
mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); mVectorState = new VectorDrawableState();
} else {
mVectorState = state;
mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
}
updateDimensionInfo(res, false);
} }
@Override @Override
@@ -359,18 +371,66 @@ public class VectorDrawable extends Drawable {
@Override @Override
public int getIntrinsicWidth() { public int getIntrinsicWidth() {
return (int) mVectorState.mVPathRenderer.mBaseWidth; return mDpiScaledWidth;
} }
@Override @Override
public int getIntrinsicHeight() { public int getIntrinsicHeight() {
return (int) mVectorState.mVPathRenderer.mBaseHeight; return mDpiScaledHeight;
} }
/** @hide */ /** @hide */
@Override @Override
public Insets getOpticalInsets() { public Insets getOpticalInsets() {
return mVectorState.mVPathRenderer.mOpticalInsets; return mDpiScaleInsets;
}
/*
* Update the VectorDrawable dimension since the res can be in different Dpi now.
* Basically, when a new instance is created or getDimension() is called, we should update
* the current VectorDrawable's dimension information.
* Only after updateStateFromTypedArray() is called, we should called this and update the
* constant state's dpi info, i.e. updateConstantStateDensity == true.
*/
void updateDimensionInfo(@Nullable Resources res, boolean updateConstantStateDensity) {
if (res != null) {
final int densityDpi = res.getDisplayMetrics().densityDpi;
final int targetDensity = densityDpi == 0 ? DisplayMetrics.DENSITY_DEFAULT : densityDpi;
if (updateConstantStateDensity) {
mVectorState.mVPathRenderer.mTargetDensity = targetDensity;
} else {
final int constantStateDensity = mVectorState.mVPathRenderer.mTargetDensity;
if (targetDensity != constantStateDensity && constantStateDensity != 0) {
mDpiScaledWidth = Bitmap.scaleFromDensity(
(int) mVectorState.mVPathRenderer.mBaseWidth, constantStateDensity,
targetDensity);
mDpiScaledHeight = Bitmap.scaleFromDensity(
(int) mVectorState.mVPathRenderer.mBaseHeight,constantStateDensity,
targetDensity);
final int left = Bitmap.scaleFromDensity(
mVectorState.mVPathRenderer.mOpticalInsets.left, constantStateDensity,
targetDensity);
final int right = Bitmap.scaleFromDensity(
mVectorState.mVPathRenderer.mOpticalInsets.right, constantStateDensity,
targetDensity);
final int top = Bitmap.scaleFromDensity(
mVectorState.mVPathRenderer.mOpticalInsets.top, constantStateDensity,
targetDensity);
final int bottom = Bitmap.scaleFromDensity(
mVectorState.mVPathRenderer.mOpticalInsets.bottom, constantStateDensity,
targetDensity);
mDpiScaleInsets = Insets.of(left, top, right, bottom);
return;
}
}
}
// For all the other cases, like either res is null, constant state is not initialized or
// target density is the same as the constant state, we will just use the constant state
// dimensions.
mDpiScaledWidth = (int) mVectorState.mVPathRenderer.mBaseWidth;
mDpiScaledHeight = (int) mVectorState.mVPathRenderer.mBaseHeight;
mDpiScaleInsets = mVectorState.mVPathRenderer.mOpticalInsets;
} }
@Override @Override
@@ -393,6 +453,7 @@ public class VectorDrawable extends Drawable {
try { try {
state.mCacheDirty = true; state.mCacheDirty = true;
updateStateFromTypedArray(a); updateStateFromTypedArray(a);
updateDimensionInfo(t.getResources(), true /* update constant state */);
} catch (XmlPullParserException e) { } catch (XmlPullParserException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} finally { } finally {
@@ -485,6 +546,7 @@ public class VectorDrawable extends Drawable {
inflateInternal(res, parser, attrs, theme); inflateInternal(res, parser, attrs, theme);
mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
updateDimensionInfo(res, true /* update constant state */);
} }
private void updateStateFromTypedArray(TypedArray a) throws XmlPullParserException { private void updateStateFromTypedArray(TypedArray a) throws XmlPullParserException {
@@ -687,7 +749,6 @@ public class VectorDrawable extends Drawable {
int mCachedRootAlpha; int mCachedRootAlpha;
boolean mCachedAutoMirrored; boolean mCachedAutoMirrored;
boolean mCacheDirty; boolean mCacheDirty;
/** Temporary paint object used to draw cached bitmaps. */ /** Temporary paint object used to draw cached bitmaps. */
Paint mTempPaint; Paint mTempPaint;
@@ -797,12 +858,12 @@ public class VectorDrawable extends Drawable {
@Override @Override
public Drawable newDrawable() { public Drawable newDrawable() {
return new VectorDrawable(this); return new VectorDrawable(this, null);
} }
@Override @Override
public Drawable newDrawable(Resources res) { public Drawable newDrawable(Resources res) {
return new VectorDrawable(this); return new VectorDrawable(this, res);
} }
@Override @Override
@@ -847,6 +908,8 @@ public class VectorDrawable extends Drawable {
int mRootAlpha = 0xFF; int mRootAlpha = 0xFF;
String mRootName = null; String mRootName = null;
int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
final ArrayMap<String, Object> mVGTargetsMap = new ArrayMap<String, Object>(); final ArrayMap<String, Object> mVGTargetsMap = new ArrayMap<String, Object>();
public VPathRenderer() { public VPathRenderer() {
@@ -886,6 +949,7 @@ public class VectorDrawable extends Drawable {
mChangingConfigurations = copy.mChangingConfigurations; mChangingConfigurations = copy.mChangingConfigurations;
mRootAlpha = copy.mRootAlpha; mRootAlpha = copy.mRootAlpha;
mRootName = copy.mRootName; mRootName = copy.mRootName;
mTargetDensity = copy.mTargetDensity;
if (copy.mRootName != null) { if (copy.mRootName != null) {
mVGTargetsMap.put(copy.mRootName, this); mVGTargetsMap.put(copy.mRootName, this);
} }