diff options
author | ztenghui <ztenghui@google.com> | 2014-09-11 14:34:20 -0700 |
---|---|---|
committer | ztenghui <ztenghui@google.com> | 2014-09-12 15:11:10 -0700 |
commit | 8490354dc651dd8f25036ef0dda7917fb33013ed (patch) | |
tree | faaea84a86e55c20dc700d5aa3b6496f97c083b3 /graphics | |
parent | 38c29ca3c75b46d631992d77af858bcd82cd04e9 (diff) | |
download | frameworks_base-8490354dc651dd8f25036ef0dda7917fb33013ed.zip frameworks_base-8490354dc651dd8f25036ef0dda7917fb33013ed.tar.gz frameworks_base-8490354dc651dd8f25036ef0dda7917fb33013ed.tar.bz2 |
Add root alpha and animation to (Animated)VectorDrawable
b/17393626
Change-Id: If6a28b072f7d4bcb2b57022d86ec784f4c0d78f1
Diffstat (limited to 'graphics')
-rw-r--r-- | graphics/java/android/graphics/drawable/VectorDrawable.java | 109 |
1 files changed, 90 insertions, 19 deletions
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java index 4407a3c..5fd8c79 100644 --- a/graphics/java/android/graphics/drawable/VectorDrawable.java +++ b/graphics/java/android/graphics/drawable/VectorDrawable.java @@ -256,21 +256,22 @@ public class VectorDrawable extends Drawable { } if (!mAllowCaching) { - mVectorState.mVPathRenderer.draw(canvas, bounds.width(), bounds.height()); + // AnimatedVectorDrawable + if (!mVectorState.hasTranslucentRoot()) { + mVectorState.mVPathRenderer.draw(canvas, bounds.width(), bounds.height()); + } else { + mVectorState.createCachedBitmapIfNeeded(bounds); + mVectorState.updateCachedBitmap(bounds); + mVectorState.drawCachedBitmapWithRootAlpha(canvas); + } } else { - Bitmap bitmap = mVectorState.mCachedBitmap; - if (bitmap == null || !mVectorState.canReuseCache(bounds.width(), - bounds.height())) { - bitmap = Bitmap.createBitmap(bounds.width(), bounds.height(), - Bitmap.Config.ARGB_8888); - Canvas tmpCanvas = new Canvas(bitmap); - mVectorState.mVPathRenderer.draw(tmpCanvas, bounds.width(), bounds.height()); - mVectorState.mCachedBitmap = bitmap; - + // Static Vector Drawable case. + mVectorState.createCachedBitmapIfNeeded(bounds); + if (!mVectorState.canReuseCache()) { + mVectorState.updateCachedBitmap(bounds); mVectorState.updateCacheStates(); } - // The bitmap's size is the same as the bounds. - canvas.drawBitmap(bitmap, 0, 0, null); + mVectorState.drawCachedBitmapWithRootAlpha(canvas); } canvas.restoreToCount(saveCount); @@ -492,6 +493,15 @@ public class VectorDrawable extends Drawable { throw new XmlPullParserException(a.getPositionDescription() + "<vector> tag requires height > 0"); } + + final float alphaInFloat = a.getFloat(R.styleable.VectorDrawable_alpha, + pathRenderer.getAlpha()); + pathRenderer.setAlpha(alphaInFloat); + + pathRenderer.mRootName = a.getString(R.styleable.VectorDrawable_name); + if (pathRenderer.mRootName != null) { + pathRenderer.mVGTargetsMap.put(pathRenderer.mRootName, pathRenderer); + } } private void inflateInternal(Resources res, XmlPullParser parser, AttributeSet attrs, @@ -646,15 +656,60 @@ public class VectorDrawable extends Drawable { } } - public boolean canReuseCache(int width, int height) { + // TODO: Support colorFilter here. + public void drawCachedBitmapWithRootAlpha(Canvas canvas) { + Paint alphaPaint = getRootAlphaPaint(); + // The bitmap's size is the same as the bounds. + canvas.drawBitmap(mCachedBitmap, 0, 0, alphaPaint); + } + + public boolean hasTranslucentRoot() { + return mVPathRenderer.getRootAlpha() < 255; + } + + /** + * @return null when there is no need for alpha paint. + */ + public Paint getRootAlphaPaint() { + Paint paint = null; + boolean needsAlphaPaint = hasTranslucentRoot(); + if (needsAlphaPaint) { + paint = new Paint(); + paint.setAlpha(mVPathRenderer.getRootAlpha()); + } + return paint; + } + + public void updateCachedBitmap(Rect bounds) { + mCachedBitmap.eraseColor(Color.TRANSPARENT); + Canvas tmpCanvas = new Canvas(mCachedBitmap); + mVPathRenderer.draw(tmpCanvas, bounds.width(), bounds.height()); + } + + public void createCachedBitmapIfNeeded(Rect bounds) { + if (mCachedBitmap == null || !canReuseBitmap(bounds.width(), + bounds.height())) { + mCachedBitmap = Bitmap.createBitmap(bounds.width(), bounds.height(), + Bitmap.Config.ARGB_8888); + } + + } + + public boolean canReuseBitmap(int width, int height) { + if (width == mCachedBitmap.getWidth() + && height == mCachedBitmap.getHeight()) { + return true; + } + return false; + } + + public boolean canReuseCache() { if (!mCacheDirty && mCachedThemeAttrs == mThemeAttrs && mCachedTint == mTint && mCachedTintMode == mTintMode && mCachedAutoMirrored == mAutoMirrored - && width == mCachedBitmap.getWidth() - && height == mCachedBitmap.getHeight() - && mCachedRootAlpha == mVPathRenderer.getRootAlpha()) { + && mCachedRootAlpha == mVPathRenderer.getRootAlpha()) { return true; } return false; @@ -729,7 +784,8 @@ public class VectorDrawable extends Drawable { float mBaseHeight = 0; float mViewportWidth = 0; float mViewportHeight = 0; - private int mRootAlpha = 0xFF; + int mRootAlpha = 0xFF; + String mRootName = null; final ArrayMap<String, Object> mVGTargetsMap = new ArrayMap<String, Object>(); @@ -747,6 +803,17 @@ public class VectorDrawable extends Drawable { return mRootAlpha; } + // setAlpha() and getAlpha() are used mostly for animation purpose, since + // Animator like to use alpha from 0 to 1. + public void setAlpha(float alpha) { + setRootAlpha((int) (alpha * 255)); + } + + @SuppressWarnings("unused") + public float getAlpha() { + return getRootAlpha() / 255.0f; + } + public VPathRenderer(VPathRenderer copy) { mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap); mPath = new Path(copy.mPath); @@ -757,6 +824,10 @@ public class VectorDrawable extends Drawable { mViewportHeight = copy.mViewportHeight; mChangingConfigurations = copy.mChangingConfigurations; mRootAlpha = copy.mRootAlpha; + mRootName = copy.mRootName; + if (copy.mRootName != null) { + mVGTargetsMap.put(copy.mRootName, this); + } } public boolean canApplyTheme() { @@ -856,7 +927,7 @@ public class VectorDrawable extends Drawable { } private void drawPath(VGroup vGroup, VPath vPath, Canvas canvas, int w, int h) { - final float scaleX = w / mViewportWidth; + final float scaleX = w / mViewportWidth; final float scaleY = h / mViewportHeight; final float minScale = Math.min(scaleX, scaleY); @@ -1219,7 +1290,7 @@ public class VectorDrawable extends Drawable { /** * Clip path, which only has name and pathData. */ - private static class VClipPath extends VPath{ + private static class VClipPath extends VPath { public VClipPath() { // Empty constructor. } |