/** * Loading the svg from the resources. * * @param context Context object to get the resources. * @param svgResource int resource id of the svg. */ public void load(Context context, int svgResource) { if (mSvg != null) return; try { mSvg = SVG.getFromResource(context, svgResource);//通过 com.caverock.androidsvg api加载 mSvg.setDocumentPreserveAspectRatio(PreserveAspectRatio.UNSCALED); } catch (SVGParseException e) { Log.e(LOG_TAG, "Could not load specified SVG resource", e); } }
/** * Render the svg to canvas and catch all the paths while rendering. * * @param width - the width to scale down the view to, * @param height - the height to scale down the view to, * @return All the paths from the svg. */ public List<SvgPath> getPathsForViewport(final int width, final int height) { final float strokeWidth = mSourcePaint.getStrokeWidth(); Canvas canvas = new Canvas() { private final Matrix mMatrix = new Matrix();
@Override public int getWidth() { return width; }
@Override public int getHeight() { return height; }
@Override public void drawPath(Path path, Paint paint) { Path dst = new Path();
/** * Rescale the canvas with specific width and height. * * @param width The width of the canvas. * @param height The height of the canvas. * @param strokeWidth Width of the path to add to scaling. * @param canvas The canvas to be drawn. */ private void rescaleCanvas(int width, int height, float strokeWidth, Canvas canvas) { if (mSvg == null) return; final RectF viewBox = mSvg.getDocumentViewBox();
/** * Default constructor. * * @param pathView The view that must be animated. */ public AnimatorBuilder(final PathView pathView) { anim = ObjectAnimator.ofFloat(pathView, "percentage", 0.0f, 1.0f); }
通过影响percentage的值,从而影响
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/** * Animate this property. It is the percentage of the path that is drawn. * It must be [0,1]. * * @param percentage float the percentage of the path. */ public void setPercentage(float percentage) { if (percentage < 0.0f || percentage > 1.0f) { throw new IllegalArgumentException("setPercentage not between 0.0f and 1.0f"); } progress = percentage; synchronized (mSvgLock) { updatePathsPhaseLocked();//更新path } invalidate();再重新绘制 }
根据progress,更新svgPath
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/** * This refreshes the paths before draw and resize. */ private void updatePathsPhaseLocked() { final int count = paths.size(); for (int i = 0; i < count; i++) { SvgUtils.SvgPath svgPath = paths.get(i); svgPath.path.reset(); svgPath.measure.getSegment(0.0f, svgPath.length * progress, svgPath.path, true); //Given a start and stop distance, return in dst the intervening segment(s). If the segment is zero-length, return false, else return true. startD and stopD are pinned to legal values (0..getLength()). If startD <= stopD then return false (and leave dst untouched). Begin the segment with a moveTo if startWithMoveTo is true // Required only for Android 4.4 and earlier svgPath.path.rLineTo(0.0f, 0.0f); } }