Code Monkey home page Code Monkey logo

vectormaster's Introduction

VectorMaster

Platform API License: MIT

This library introduces dynamic control over vector drawables. Each and every aspect of a vector drawable can be controlled dynamically (via Java instances), using this library.

Features :

  • Control : Control every attribute related to path, group, vector and clip-path like color, alpha, strokeWdith, translation, scale, rotation etc.
  • Clip Paths : The library supports clip paths.
  • Trimming : The library allows trimming of path by using trimEnd, trimStart and trimOffset parameters.

Usage

Just add the following dependency in your app's build.gradle

dependencies {
      compile 'com.sdsmdg.harjot:vectormaster:1.1.3'
}

Background and Working

VectorDrawables are really helpful for removing scaling problem but they lack control. Most of the changes to vector drawables are only possible by creating an AnimatedVectorDrawable and also defining animations. All of this is good but lacks control that may be required during runtime.

For example, if we need to change vector's properties (Say, color) based on a user action (Say, if user is choosing the theme of app). We can achieve this using AnimatedVectorDrawable but only to an extent, this approach can't be used if user action leads to an infinite number of cases (Say, if user picks up a random color for theme) and we need to change property of the vector for each case. Thus we need a mechanism that can be used to change a vector's properties at runtime using basic methods like setColor, setScale, setTranslation etc. This is where this library comes in.

The library works as follows :

  • First the vector.xml(the VectorDrawable that we wish to control), is parsed using XmlPullParser and the attributes are stored in Models corresponding to the tag.
  • vector attributes are stored in VectorModel, group attributes in GroupModel, path atrributes in PathModel and clip-path attributes in ClipPathModel. The hierarchy is as follows :


  • The pathData in PathModel is then parsed using PathParser.java; It parses the string data and converts it into a Path object.
  • All the transformations, scaling etc are done using Matrices after the Path object is built. All this is done prior to the first draw on canvas.
  • At first draw we have the same output as we should have got if we used inbuilt methods to draw the vector.xml using srcCompat.
  • Now, all Models are accessible via getModelByName(...) public methods that can be directly called via the instance of VectorMasterView that we get using findViewById(...).
  • If we wish to change any value, we just need to call model.setParamter(...). model is of type VectorModel, GroupModel, PathModel or ClipPathModel. parameter can be anything like color, scale, rotation etc. depending on the model we are using.
  • After setting a paramter the necesarry paints and paths are rebuilt, scaled, transformed etc.
  • A call to update method repaints the canvas with the required changes.

Examples

ic_heart.xml (This is the original vector that has been used in all examples)

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:name="outline"
        android:pathData="M20.84,4.61a5.5,5.5 0,0 0,-7.78 0L12,5.67l-1.06,-1.06a5.5,5.5 0,0 0,-7.78 7.78l1.06,1.06L12,21.23l7.78,-7.78 1.06,-1.06a5.5,5.5 0,0 0,0 -7.78z"
        android:strokeLineCap="round"
        android:strokeColor="#5D5D5D"
        android:fillColor="#00000000"
        android:strokeWidth="2"
        android:strokeLineJoin="round"/>
</vector>

Example 1 (Simple Color change)

XML

<com.sdsmdg.harjot.vectormaster.VectorMasterView
        android:id="@+id/heart_vector"
        android:layout_width="150dp"
        android:layout_height="150dp"
        app:vector_src="@drawable/ic_heart" />

Java

VectorMasterView heartVector = (VectorMasterView) findViewById(R.id.heart_vector);

// find the correct path using name
PathModel outline = heartVector.getPathModelByName("outline");

// set the stroke color
outline.setStrokeColor(Color.parseColor("#ED4337"));

// set the fill color (if fill color is not set or is TRANSPARENT, then no fill is drawn)
outline.setFillColor(Color.parseColor("#ED4337"));

Result

Example 2 (Trim paths)

XML

<com.sdsmdg.harjot.vectormaster.VectorMasterView
        android:id="@+id/heart_vector"
        android:layout_width="150dp"
        android:layout_height="150dp"
        app:vector_src="@drawable/ic_heart" />

Java

VectorMasterView heartVector = (VectorMasterView) findViewById(R.id.heart_vector);

// find the correct path using name
PathModel outline = heartVector.getPathModelByName("outline");

// set trim path start (values are given in fraction of length)
outline.setTrimPathStart(0.0f);

// set trim path end (values are given in fraction of length)
outline.setTrimPathEnd(0.65f);

Result

Example 3 (Simple color animation using ValueAnimator)

XML

<com.sdsmdg.harjot.vectormaster.VectorMasterView
        android:id="@+id/heart_vector"
        android:layout_width="150dp"
        android:layout_height="150dp"
        app:vector_src="@drawable/ic_heart" />

Java

VectorMasterView heartVector = (VectorMasterView) findViewById(R.id.heart_vector);

// find the correct path using name
PathModel outline = heartVector.getPathModelByName("outline");

outline.setStrokeColor(Color.parseColor("#ED4337"));

heartVector.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {

    	// initialize valueAnimator and pass start and end color values
        ValueAnimator valueAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), Color.WHITE, Color.parseColor("#ED4337"));
        valueAnimator.setDuration(1000);

        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {

            	// set fill color and update view
                outline.setFillColor((Integer) valueAnimator.getAnimatedValue());
                heartVector.update();
            }
        });
        valueAnimator.start();
    }
});

Result

Example 4 (Simple trim animation using ValueAnimator)

XML

<com.sdsmdg.harjot.vectormaster.VectorMasterView
        android:id="@+id/heart_vector"
        android:layout_width="150dp"
        android:layout_height="150dp"
        app:vector_src="@drawable/ic_heart" />

Java

VectorMasterView heartVector = (VectorMasterView) findViewById(R.id.heart_vector);

// find the correct path using name
PathModel outline = heartVector.getPathModelByName("outline");

outline.setStrokeColor(Color.parseColor("#ED4337"));
outline.setTrimPathEnd(0.0f);

heartVector.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {

    	// initialise valueAnimator and pass start and end float values
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
        valueAnimator.setDuration(1000);

        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {

            	// set trim end value and update view
                outline.setTrimPathEnd((Float) valueAnimator.getAnimatedValue());
                heartVector.update();
            }
        });
        valueAnimator.start();
    }
});

Result

Complex animations

The above examples are just the basic use cases and are meant to serve as a quick start to using the library. For more complex animations and use cases involving clip-paths and groups, head to AnimationExamples

If your animation doesn't involve any clip-path or group, then you may use RichPath library developed by tarek360. This library is really useful, if you don't want to indulge in too much mathematics or logic.

Using as a Custom Drawable

The library also provide custom drawable implementation in form of VectorMasterDrawable. It provides the same control over the vector, but allows the user to use the drawable as per its wish, for e.g. as a Compound Drawable in TextView, or as the source drawable in ImageView; basically any use case that involves a Drawable can be replaced by VectorMasterDrawable.

Example

XML

<TextView
    android:id="@+id/text_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Heart"
    android:textSize="30sp" />

<ImageView
    android:id="@+id/image_view"
    android:layout_width="75dp"
    android:layout_height="75dp"/>

Java

// Instantiate the custom drawable
VectorMasterDrawable vectorMasterDrawable = new VectorMasterDrawable(this, R.drawable.ic_heart);

// Set top drawable for TextView
TextView textView = (TextView) findViewById(R.id.text_view);
textView.setCompoundDrawablesWithIntrinsicBounds(null, vectorMasterDrawable, null, null);

// Set background drawable for ImageView
ImageView imageView = (ImageView) findViewById(R.id.image_view);
imageView.setImageDrawable(vectorMasterDrawable);

// Set tht stroke color of the drawable
PathModel pathModel = vectorMasterDrawable.getPathModelByName("outline");
pathModel.setStrokeColor(Color.parseColor("#ED4337"));

Result

Limitations

  1. The PathParser.java has been extracted from Android source code of version 5.1.1. After this version all the parsing code was shifted to native for efficiency. I have incorporated some of the changes from the native code into the PathParser.java, but still sometimes parsing errors occur. I have also included a 3rd party parser from Android-Image-Shape. To use this parser instead of the default one, set use_legacy_parser="false". This may help in certain situations but not always. If you find any vector that is not being drawn properly, please file an issue and include the vector.
  2. Path morphing is not supported as of now. I would like to support path morphing between incompatible vectors as well (using techniques mentioned here by Alex Lockwood).
  3. Vector tints are not supported yet.
  4. This library doesn't have dedicated methods for supporting animations. It just exposes the paths, groups etc. for the user to use as he wants, thus for making animations a lot of maths and logic is involved. If you want dedicated methods for animations use RichPath library developed by tarek360.

License

VectorMaster is licensed under MIT license. View license.

vectormaster's People

Contributors

harjot-oberai avatar jaysondc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vectormaster's Issues

drawable resources versus xml (suggestion)

At first, I could not get the widget working for api 23 marshmallow. The vector graphics were in the res/drawable. It worked fine for api 24 nougat though. I got the error message "resource not found" on api 23.

The solution was to put the vector xml in the res/xml folder instead. Now the XML parser can find the resources on bot api 23 and 24. I noticed that the Android build system modifies the drawables directory name, it attaches -v23 or -v24 to the directory name while creating the apk.

Maybe the documentation should mention that the res/xml is a better location for the vector images then the drawables for the widget? What are your thoughts?

Exception during setContentView

Hi,

I want_ to try this lib, but I get an exception. Here is a cutout of the exception.

Caused by: android.view.InflateException: Binary XML file line #115: Error inflating class com.sdsmdg.harjot.vectormaster.VectorMasterView at android.view.LayoutInflater.createView(LayoutInflater.java:613) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687) at android.view.LayoutInflater.rInflate(LayoutInflater.java:746) at android.view.LayoutInflater.rInflate(LayoutInflater.java:749) at android.view.LayoutInflater.rInflate(LayoutInflater.java:749) at android.view.LayoutInflater.inflate(LayoutInflater.java:489) at android.view.LayoutInflater.inflate(LayoutInflater.java:396) at android.view.LayoutInflater.inflate(LayoutInflater.java:352) at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:270) at android.app.Activity.setContentView(Activity.java:1881) at de.ratiodata.scan4agree21.activity.TonerActivity.onCreate(TonerActivity.java:26) at android.app.Activity.performCreate(Activity.java:5104) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)  at android.app.ActivityThread.access$600(ActivityThread.java:141)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)  at android.os.Handler.dispatchMessage(Handler.java:99)  at android.os.Looper.loop(Looper.java:137)  at android.app.ActivityThread.main(ActivityThread.java:5041)  at java.lang.reflect.Method.invokeNative(Native Method)  at java.lang.reflect.Method.invoke(Method.java:511)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)  at dalvik.system.NativeStart.main(Native Method)  Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Constructor.constructNative(Native Method) at java.lang.reflect.Constructor.newInstance(Constructor.java:417) at android.view.LayoutInflater.createView(LayoutInflater.java:587) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)  at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)  at android.view.LayoutInflater.rInflate(LayoutInflater.java:749)  at android.view.LayoutInflater.rInflate(LayoutInflater.java:749)  at android.view.LayoutInflater.inflate(LayoutInflater.java:489)  at android.view.LayoutInflater.inflate(LayoutInflater.java:396)  at android.view.LayoutInflater.inflate(LayoutInflater.java:352)  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:270)  at android.app.Activity.setContentView(Activity.java:1881)  at de.ratiodata.scan4agree21.activity.TonerActivity.onCreate(TonerActivity.java:26)  at android.app.Activity.performCreate(Activity.java:5104)  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)  at android.app.ActivityThread.access$600(ActivityThread.java:141)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)  at android.os.Handler.dispatchMessage(Handler.java:99)  at android.os.Looper.loop(Looper.java:137)  at android.app.ActivityThread.main(ActivityThread.java:5041)  at java.lang.reflect.Method.invokeNative(Native Method)  at java.lang.reflect.Method.invoke(Method.java:511)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)  at dalvik.system.NativeStart.main(Native Method)  Caused by: android.content.res.Resources$NotFoundException: File res/drawable-mdpi-v4/image_toner_singeltoner.png from xml type xml resource ID #0x7f06006b at android.content.res.Resources.loadXmlResourceParser(Resources.java:2186) at android.content.res.Resources.loadXmlResourceParser(Resources.java:2141) at android.content.res.Resources.getXml(Resources.java:902) at com.sdsmdg.harjot.vectormaster.VectorMasterView.buildVectorModel(VectorMasterView.java:86) at com.sdsmdg.harjot.vectormaster.VectorMasterView.init(VectorMasterView.java:75) at com.sdsmdg.harjot.vectormaster.VectorMasterView.<init>(VectorMasterView.java:51) at java.lang.reflect.Constructor.constructNative(Native Method)  at java.lang.reflect.Constructor.newInstance(Constructor.java:417)  at android.view.LayoutInflater.createView(LayoutInflater.java:587)  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)  at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)  at android.view.LayoutInflater.rInflate(LayoutInflater.java:749)  at android.view.LayoutInflater.rInflate(LayoutInflater.java:749)  at android.view.LayoutInflater.inflate(LayoutInflater.java:489)  at android.view.LayoutInflater.inflate(LayoutInflater.java:396)  at android.view.LayoutInflater.inflate(LayoutInflater.java:352)  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:270)  at android.app.Activity.setContentView(Activity.java:1881)  at de.ratiodata.scan4agree21.activity.TonerActivity.onCreate(TonerActivity.java:26)  at android.app.Activity.performCreate(Activity.java:5104)  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)  at android.app.ActivityThread.access$600(ActivityThread.java:141)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)  at android.os.Handler.dispatchMessage(Handler.java:99)  at android.os.Looper.loop(Looper.java:137)  at android.app.ActivityThread.main(ActivityThread.java:5041)  at java.lang.reflect.Method.invokeNative(Native Method)  at java.lang.reflect.Method.invoke(Method.java:511)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)  at dalvik.system.NativeStart.main(Native Method)  Caused by: java.io.FileNotFoundException: Corrupt XML binary file at android.content.res.AssetManager.openXmlAssetNative(Native Method) at android.content.res.AssetManager.openXmlBlockAsset(AssetManager.java:487) at android.content.res.Resources.loadXmlResourceParser(Resources.java:2168) at android.content.res.Resources.loadXmlResourceParser(Resources.java:2141)  at android.content.res.Resources.getXml(Resources.java:902)  at com.sdsmdg.harjot.vectormaster.VectorMasterView.buildVectorModel(VectorMasterView.java:86)  at com.sdsmdg.harjot.vectormaster.VectorMasterView.init(VectorMasterView.java:75)  at com.sdsmdg.harjot.vectormaster.VectorMasterView.<init>(VectorMasterView.java:51)  at java.lang.reflect.Constructor.constructNative(Native Method)  at java.lang.reflect.Constructor.newInstance(Constructor.java:417)  at android.view.LayoutInflater.createView(LayoutInflater.java:587)  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)  at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)  at android.view.LayoutInflater.rInflate(LayoutInflater.java:749)  at android.view.LayoutInflater.rInflate(LayoutInflater.java:749)  at android.view.LayoutInflater.inflate(LayoutInflater.java:489)  at android.view.LayoutInflater.inflate(LayoutInflater.java:396)  at android.view.LayoutInflater.inflate(LayoutInflater.java:352)  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:270)  at android.app.Activity.setContentView(Activity.java:1881)  at de.ratiodata.scan4agree21.activity.TonerActivity.onCreate(TonerActivity.java:26)  at android.app.Activity.performCreate(Activity.java:5104)  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)  at android.app.ActivityThread.access$600(ActivityThread.java:141)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)  at android.os.Handler.dispatchMessage(Handler.java:99)  at android.os.Looper.loop(Looper.java:137)  at android.app.ActivityThread.main(ActivityThread.java:5041)  at java.lang.reflect.Method.invokeNative(Native Method)  at java.lang.reflect.Method.invoke(Method.java:511)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)  at dalvik.system.NativeStart.main(Native Method) 

Can you say what it is or where is my mistake?

Best regards
LiTe

Set app:vector_src Programmatically

I'm having some troubles in order to achive this I got an xml file as my drawable, if I put the drawable on the xml it works nice, but I need to change the source to another view programmatically.
I've tried different methods like:

  • setBackground()

  • setBackgroudResource()

But none of them works.

Gradients not supported?

My vector image has a gradient but it isn't painted when using the VectorMasterDrawable, is this expected?

I realize this is a v24+ feature.

how to create a vector drawable working with this library

Hi, thanks for this exciting library.
I have a question.
I use simple vectors in the android studio to supply this library but my vectors don't animate as I want.
I think that's beacuse of how vectors define in xml.
for seeing my problem you just need set a one of defalut vectors to VectorMasterView.
so my question is how should I create a vector that works with this great library?
I hope best wishes for you.

Vector drawable not drawn properly

Hi.

I'm having a display bug when I want to use this vector drawable (SVG file exported with Adobe Illustrator, then converted to VectorDrawable) in a VectorMasterDrawable object. Some paths are missing or deformed, but only with your library, not with the Android drawable API. Can you explain me why ?

ic_201.zip

Thank you in advance.

Question: possible to decode VectorDrawable from byte array?

Sadly starting from Android Q (or later, if you use the legacy flag), Google forces to use SAF instead of File.
This means that parsing APK files is almost impossible, so I plan to use apk-parser library.

Sadly, the library doesn't offer to parse the VectorDrawable of the app-icons (written about here), but instead if offers its data as byte array.

My question:
Does this library provide a way to get an instance of VectorDrawable from byte-array? If so, how?

If not, do you know perhaps of a way to do it? Maybe via the support library?

Different result using VectorMasterView ?

Using ImageView (as expecting)

<ImageView
        app:srcCompat="@drawable/man_body"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

But using VectorMasterView

<com.sdsmdg.harjot.vectormaster.VectorMasterView
        app:use_legacy_parser="false"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:vector_src="@drawable/man_body" />

Why result are different with same vector image, there are any criteria for VectorMasterView ?

Vector with multiple paths is drawn with only one

I really can't make heads or tails of it ... The only path that is drawn correctly is "phone" but "button", "display" and "outline" are not drawn at all .. I tried removing "phone" path completely but that way nothing is shown. Classic ImageView renders everything perfectly. The only thing that comes to mind is that the other paths are malformed but they came from the same generation source as the working one

Here is the vector:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="218dp"
    android:height="267dp"
    android:viewportHeight="269"
    android:viewportWidth="220">
<group>
    <path
        android:name="phone"
        android:fillColor="#FFF"
        android:fillType="evenOdd"
        android:pathData="M186.224,267l-156.444,-0.342C13.296,266.624 -0.038,253.224 0,236.728L0.721,-94.06C0.76,-111.186 14.662,-125.038 31.776,-125l155.302,0.338c17.114,0.038 30.956,13.95 30.922,31.076l-0.721,329.643c-0.034,17.125 -13.941,30.98 -31.055,30.943zM201.408,213L202,-76.565 16.592,-77 16,212.57l185.408,0.43zM92,229c-5.523,0 -10,4.477 -10,10s4.477,10 10,10h35c5.523,0 10,-4.477 10,-10s-4.477,-10 -10,-10L92,229z" />


    <path
        android:fillColor="#00000000"
        android:name="outline"
        android:fillType="evenOdd"
        android:pathData="M187.224,267l-156.444,-0.342C14.296,266.624 0.962,253.224 1,236.728L1.721,-94.06c0.038,-17.126 13.941,-30.978 31.055,-30.94l155.302,0.338c17.114,0.038 30.956,13.95 30.922,31.076l-0.721,329.643c-0.034,17.125 -13.941,30.98 -31.055,30.943z"
        android:strokeColor="@color/cool_grey"
        android:strokeWidth="2" />


    <path
        android:name="display"
        android:pathData="M201.408,213L16,212.57 16.592,-77 206,-76.565z"
        android:fillColor="@color/cool_grey"
        android:fillType="evenOdd"/>
    <group
        android:name="buttonGroup"
        android:translateX="82"
        android:translateY="229">
        <path
            android:name="button"
            android:fillColor="@color/cool_grey"
            android:fillType="evenOdd"
            android:pathData="M10,0L45,0A10,10 0,0 1,55 10L55,10A10,10 0,0 1,45 20L10,20A10,10 0,0 1,0 10L0,10A10,10 0,0 1,10 0z" />
    </group>
</group>
</vector>

Bug: VectorDrawable not shown correctly

I've tried to show this VectorDrawable, and it doesn't show the same on VectorMasterView compared to ImageView:

boy.zip

It doesn't show the eyes and the mouth, on both the IDE preview and when running the app:

image

Using this:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:gravity="center" android:orientation="vertical"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/imageView" android:layout_width="150dp" android:layout_height="150dp"
        android:src="@drawable/boy" />

    <com.sdsmdg.harjot.vectormaster.VectorMasterView
        android:id="@+id/vectorMasterView" android:layout_width="150dp" android:layout_height="150dp"
        app:vector_src="@drawable/boy" />
</LinearLayout>

Sample:

VectorDrawableChangerTest.zip

Strange vector problems when the VectorMasterView size changes

I have a VectorMasterView inside a ConstraintLayout, with all sides constrained to parent, and width and height set to match_constraint. I've noticed that if the width or the height of the VectorMasterView change, the vector inside either disappears or is not rendered properly (e.g., the vector is oversized, is undersized, is not centered anymore).

The only way I found to prevent this behavior is to set a fixed width and a fixed height, but it's not what I need.

Is there anything I can do?

Multiply path scale problem

Hi, I have a vector image (vector_img.xml):

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="22dp"
    android:height="22dp"
    android:viewportWidth="300"
    android:viewportHeight="300">

    <path
        android:fillColor="#FF000000"
        android:pathData="M 150 0 C 232.842712475 0 300 67.1572875254 300 150 C 300 232.842712475 232.842712475 300 150 300 C 67.1572875254 300 0 232.842712475 0 150 C 0 67.1572875254 67.1572875254 0 150 0 Z" />

    <path
        android:fillColor="#FFFFFFFF"
        android:pathData="M 150 30 C 216.27416998 30 270 83.7258300203 270 150 C 270 216.27416998 216.27416998 270 150 270 C 83.7258300203 270 30 216.27416998 30 150 C 30 83.7258300203 83.7258300203 30 150 30 Z" />

    <path
        android:fillColor="#FF000000"
        android:pathData="M 150 60 C 199.705627485 60 240 100.294372515 240 150 C 240 199.705627485 199.705627485 240 150 240 C 100.294372515 240 60 199.705627485 60 150 C 60 100.294372515 100.294372515 60 150 60 Z" />

</vector>

I'm trying to scale vector programmatically like this:

VectorMasterDrawable vectorDrawable = new VectorMasterDrawable(context, R.drawable.vector_img);
vectorDrawable.setScaleX(1.5f);
vectorDrawable.setScaleY(1.5f);

The result is not happy:

from

Perhaps the problem is that when we scale vector we can't set pivot points? Or am I doing something wrong?)

Thanks

How to use Paint with VectorMasterDrawable?

Hi, thanks for this awesome library.
I am using VectorMasterDrawable with Paint to set color with ColorFilter, but nothing is drawing. What i do wrong?
All is ok, if i use setColor(), but I need ColorFilter.

Resize Vector

Hi,

Is there way, using this library dynamically resize vector drawables, (programatically, maybe)?

Thanks

Performance issue

Hi,

It appears your library can take a lot of time when loading complex drawables (over 15 paths), especially on older devices.

You use XmlPullParser, but do you think VDT-XML library could be a better choice to speed up parsing ?

API 16 not visible VectorMasterView, VectorMasterDrawable

hello.
your VectorMaster is very good.
but It is not visible in API 16.

first of all, Successfully registered VectorMasterView on XML.
Then, animation was made in Java source using PathModel.

However, when the app was running, no images were visible.

So i registered ImageView to the XML and did setImageDrawable to ImageView as VectorMasterDrawable from java source.

but not visible too.

Let me show you my XML and Java source parts.

[xml]

<ImageView
            android:id="@+id/header_menu"
            android:layout_width="30dp"
            android:layout_height="24dp"
            android:layout_centerVertical="true"/>

[java]

headerMenuView = (ImageView) activity.findViewById(R.id.header_menu);
headerMenuVMView = new VectorMasterDrawable(mContext, R.drawable.ic_menu);
headerMenuView.setImageDrawable(headerMenuVMView);

VectorMasterDrawable menuView = headerMenuVMView;
final GroupModel menuGroupModel = menuView.getGroupModelByName("menu_group");
final PathModel menuPathModel1 = menuView.getPathModelByName("menu1");

menuGroupModel.setRotation(MathUtil.lerp(0, (float) 360, offset));
menuPathModel1.setTrimPathEnd(1 - offset);

why not show image?


You can check VectorMaster Demos when operating the API 16.

Error when trying to find a path in a vector with multiple paths.

In my Android application I'm using a for loop to reference different paths in my VectorDrawable. However, every time I call myVector.getPathModelByName(myString), I get the following error:

java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at com.sdsmdg.harjot.vectormaster.VectorMasterView.getPathModelByName(VectorMasterView.java:337)

I've been messing around with the vector drawable to fix this. I tried just referencing the first path in the drawable in every loop iteration, and that seems to work fine, so there might be a problem looking past the first path. Is this a bug or am I using the class wrong?

Is there a way of using VectorMaster with remote views?

Hey,

I'm trying to modify a vector image in a persistent notification. Can I do this with VectorMaster?

The normal way of changing things in a notification is via a RemoteView

RemoteViews notificationRemoteView = new RemoteViews(context.getPackageName(), R.layout.persistent_notification);

but I'm not sure how to get a VectorMaster object from the RemoteView once I have it.

Support for Gradient Fill Colors

I have the following Vector Drawable..

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt"
    android:width="78dp"
    android:height="120dp"
    android:viewportWidth="78"
    android:viewportHeight="120">
  <path
      android:pathData="M8,111a31,9 0,1 0,62 0a31,9 0,1 0,-62 0z"
      android:fillColor="#000"
      android:fillAlpha=".08"
      android:fillType="evenOdd"/>
  <path
      android:name="fillColorPath"
      android:pathData="M39,109c24.667,-33.044 37,-56.377 37,-70C76,18.565 59.435,2 39,2S2,18.565 2,39c0,13.623 12.333,36.956 37,70zM39,54c7.732,0 14,-6.268 14,-14s-6.268,-14 -14,-14 -14,6.268 -14,14 6.268,14 14,14z"
      android:strokeLineJoin="round"
      android:strokeWidth="4"
      android:strokeColor="#FF50BEFF"
      android:fillType="evenOdd">
    <aapt:attr name="android:fillColor">
      <gradient 
          android:startY="39.25312"
          android:startX="39"
          android:endY="40.31242"
          android:endX="39"
          android:type="linear">
        <item android:offset="0" android:color="#FF50BEFF"/>
        <item android:offset="1" android:color="#FF4BAFFF"/>
      </gradient>
    </aapt:attr>
  </path>
</vector>

Unfortunately, since the fillColor is set to a gradient in the fillColorPath path, PathModel.getFillColor returns 0, which is incorrect. I'm gathering this is not supported?

Use the RichPath Animator to write less code

Hi @harjot-oberai
I have developed a new library called RichPath
It gives full Animation Control on Paths and VectorDrawables

It will make the path animation code shorter

for example, the Search-Back animation sample which is in the VectorMaster examples.

Before:

      Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                count++;
                if (count >= 50) {
                    if (searchBackState == 0) {
                        circleTrimEnd -= 1.0f / 20;
                        stemTrimStart += 0.75f / 20;
                        stemTrimEnd += (1 - 0.185f) / 20;
                        arrowHeadBottomTrimEnd += 1.0f / 20;
                        arrowHeadTopTrimEnd += 1.0f / 20;
                        if (circleTrimEnd <= 0) {
                            searchBackState = 1;
                            count = 0;
                        }
                    } else if (searchBackState == 1) {
                        arrowHeadBottomTrimEnd -= 1.0f / 20;
                        arrowHeadTopTrimEnd -= 1.0f / 20;
                        stemTrimStart -= 0.75f / 20;
                        stemTrimEnd -= (1 - 0.185f) / 20;
                        circleTrimEnd += 1.0f / 20;
                        if (circleTrimEnd >= 1) {
                            searchBackState = 0;
                            count = 0;
                        }
                    }

                    searchCircle.setTrimPathEnd(circleTrimEnd);
                    stem.setTrimPathEnd(stemTrimEnd);
                    stem.setTrimPathStart(stemTrimStart);
                    arrowUp.setTrimPathEnd(arrowHeadTopTrimEnd);
                    arrowDown.setTrimPathEnd(arrowHeadBottomTrimEnd);

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            searchBackView.update();
                        }
                    });
                }

            }
        }, 1000, 1000 / 60);

After: (By using the RichPath Animator)

RichPathAnimator.animate(stem)
                    .trimPathStart(0f, 0.75f)
                    .trimPathEnd(0.185f, 1f)
                    .andAnimate(searchCircle)
                    .trimPathEnd(1, 0)
                    .andAnimate(arrowTop, arrowBottom)
                    .trimPathEnd(0, 1)
                    .start();

No option to update vector model

There is no option to update the vector model in vectorMasterDrawable. There should be option to update the viewport width and height etc.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.