Android Animated Vector Drawable: change rotation degree at runtime - android

I'm trying to make an Android vector animation, which contains a rotation on a vectorial group. Basically, if the degree transition would be constant, I would use those resources:
My VectorDrawable:
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportHeight="600"
android:viewportWidth="600">
<group
android:name="myRotationGroup"
android:pivotX="300.0"
android:pivotY="300.0"
android:rotation="0">
<path
android:name="myName"
android:fillColor="#000000"
android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z"/>
</group>
</vector>
My AnimatedVectorDrawable:
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="#drawable/my_vector_drawable" >
<target
android:name="myRotationGroup"
android:animation="#animator/my_rotation" />
</animated-vector>
And my ObjectAnimator:
<objectAnimator
android:duration="500"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360" />
However, as you can see above, the final degree of rotation is set in the ObjectAnimator resource, as 360° for instance.
For my animation, how can I change programmatically this final value? The rotation degree need to be computed with some other data, so I don't know the target value before the animation starts.
Thank you for your help!

I think the solution is to create an object of ObjectAnimator in the class like this
ObjectAnimator myRotation = ObjectAnimator.ofFloat(target,"rotation",360f);
myRotation.setDuration(500);
myRotation.start(); // this will start the animation
// here target is the object of the view on which you want to apply this animation
// and you can change this 360f to any number at which degree you want to rotate
for more information check this out

Related

How to Create Android Animated Vector Drawable

I have https://lottiefiles.com/share/gordjiyb Lottie file for which I want to create Android Animated Vector Drawable,
We have used the Fresco library and converted the Lottie file into GIF in the drawable folder, which is taking 600 kb space.
I am sure Animated Vector Drawable will be more space sufficient.
You can do the next
Create a file that it is a html
Import the file in the assets folder
Add an webview component in the view
Load the file in the component
package com.example.myapplication
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.webkit.WebView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val webview = findViewById(R.id.webview)
webview.loadUrl("file:///android_asset/index.html")
}
}
create an animation inside the res/animator resource folder (create it if it doesn't exist) and let's call it expand1 like so:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially">
<set>
<objectAnimator
android:propertyName="scaleX"
android:duration="1000"
android:valueTo="0.5"
android:interpolator="#android:anim/linear_interpolator"/>
<objectAnimator
android:propertyName="scaleY"
android:duration="1000"
android:valueTo="0.5"
android:interpolator="#android:anim/linear_interpolator"/>
</set>
<set>
<objectAnimator
android:propertyName="scaleX"
android:duration="1000"
android:valueTo="1.5"
android:interpolator="#android:anim/linear_interpolator"/>
<objectAnimator
android:propertyName="scaleY"
android:duration="1000"
android:valueTo="1.5"
android:interpolator="#android:anim/linear_interpolator"/>
</set>
</set>
this will create an object animator that will in turn scale up and down an icon
then create 3 more expand2 expand3 expand4
on each one change the scaleX and scaleY to be from 0.5 to 1.5 , to 0.7 to 1.3 etc, according to how big your circles should be at minimum and maximum
then create your vector drawable (ic_sound.xml) like so:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group
android:name="icon">
<path
android:fillColor="#android:color/white"
android:pathData=" draw the microphone icon here "/>
</group>
<group
android:name="circle1">
<path
android:fillColor="#android:color/holo_green_light"
android:fillAlpha="0.2"
android:pathData=" draw the darkest circle here "/>
</group>
repeat three more times for circle2, circle3 and circle4 with different fillAlphas
</vector>
finally create a vector drawable like so:
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="#drawable/ic_sound">
<target
android:name="circle1"
android:animation="#animator/expand1" />
<target
android:name="circle2"
android:animation="#animator/expand2" />
<target
android:name="circle3"
android:animation="#animator/expand3" />
<target
android:name="circle4"
android:animation="#animator/expand4" />
</animated-vector>
what this does is that it tells the ic_sound vector, to apply an animator to each group , so circle1 will expand from 0.5 to 1.5 , circle 2 will expand from 0.7 to 1.3 and so on
you can play with the times (if you want the animation to last longer) how long it will play , the interpolators (to add an accelerate or decelerate effect) to make it look as you wish

Animating path of Vector Drawable in Android

I'm trying to animate my exported SVG file from illustrator in my Android app by animating the line or path of character to show to the users how to properly write a character(ex: Japanese & Chinese character). But when I run the application, it only animates the edge/stroke of a character and brings back to its original state. Does anyone has already experienced this case before?
Here is my SVG drawable
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="300dp"
android:height="300dp"
android:viewportWidth="300.0"
android:viewportHeight="300.0">
<path
android:name="invertu"
android:fillColor="#FF000000"
android:pathData="M21.23,263.43c0.68,-14.76 6.03,-28.9
9.58,-43.12c3.82,-15.3 6.51,-30.8 10.68,-46.04c4.22,-15.46 9.06,-30.74
14.02,-45.97c3.7,-11.38 7.53,-22.54 14.07,-32.66c14.19,-21.95 43.47,-29.83
67.74,-33.8c13.6,-2.22 27.52,-2.66 41.27,-2.32c10.71,0.27 21.44,2.13
31.29,6.5c28.73,12.76 43.98,42.42 53.04,70.95c5.67,17.85 9,36.29
12.31,54.69c4.36,24.27 7.8,48.7 8.3,73.39c0.19,9.66 15.19,9.68
15,0c-0.65,-32.46 -6.33,-64.51 -12.34,-96.33c-4.07,-21.5 -9.94,-42.7
-19.22,-62.57c-8.76,-18.76 -21.57,-35.7 -38.92,-47.24c-20.15,-13.41
-44.1,-15.18 -67.61,-14.26c-24.9,0.97 -49.66,5.88 -72.26,16.55c-20.76,9.8
-33.38,26.41 -41.69,47.37c-4.61,11.65 -8.1,23.81 -11.83,35.77c-4.22,13.53
-8.13,27.16 -11.53,40.92c-3.27,13.2 -5.45,26.61 -9.05,39.73c-3.47,12.65
-7.23,25.26 -7.84,38.45C5.79,273.11 20.79,273.06 21.23,263.43L21.23,263.43z"
android:strokeLineCap="round"
android:strokeLineJoin="round"
android:strokeWidth="3"
android:trimPathEnd="0"/> </vector>
and this is my animated vector
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:drawable="#drawable/ic_ba">
<target android:name="invertu">
<aapt:attr name="android:animation">
<objectAnimator
android:duration="1000"
android:interpolator="#android:interpolator/fast_out_slow_in"
android:propertyName="trimPathEnd"
android:valueFrom="0"
android:valueTo="1"/>
</aapt:attr>
</target>
The VSG that I've exported from Adobe Illustrator becomes transparent in the center, only the outline animates from one point to another end.
TIA
trimPathStart and trimPathEnd are intended to only set the start and end of the stroke (outline) of the path. If you want the filled part of the path to be animated you'll have to do it another way.
If the line shapes in your characters have a constant width, then just draw them as a thick line - rather than an outline like it is now. If you do that, the lines will be able to be animated using the trimPath method.

Animated Vector Drawable Animation does not work

I can't figure out why my Animated Vector is not working. I can see the first path but the second path that I want to animate as an addition to the first path is not showing. This is how my code looks like:
<?xml version="1.0" encoding="utf-8"?>
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:height="24dp"
android:width="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0" >
<path
android:name="v"
android:strokeColor="#000000"
android:strokeWidth="3"
android:pathData="M6,11 l3.5, 4 l0, 0" />
</vector>
</aapt:attr>
<target android:name="v" >
<aapt:attr name="android:animation">
<set>
<objectAnimator
android:duration="1000"
android:propertyName="pathData"
android:valueFrom="M6,11 l3.5, 4 l0, 0"
android:valueTo="M6,11 l3.5, 4 l8, -7"
android:valueType="pathType"/>
</set>
</aapt:attr>
</target>
</animated-vector>
So, M6,11 l3.5, 4 l0, 0 is showing on the screen but not M6,11 l3.5, 4 l8, -7
I tried copy the example from the bottom of the google docs here and that did work. My file animated correctly if I use their code which tells me I do start the animation correctly. Is this a typo or something wrong with my path data?
I tested my drawable in a new project and to my surprise it was working fine.
I was using com.android.support:design:25.1.0 in my first project and it turns out degrading to com.android.support:design:24.2.0 made it work.
After testing a bit more I found that changing from app:srcCompat="#drawable/animated_vector" to android:src="#drawable/animated_vector" on my ImageView made it work for com.android.support:design:25.1.0 as well.
Im not sure whats going on but now it works at least. If someone has more details on this please let me know. I thought we where supposed use srcCompat for vector drawables.

Android animated vector rotation - properly starting animation

I'm using <animated-vector> to rotate an arrow:
<target
android:name="rotationGroup"
android:animation="#animator/animator" />
and the animator:
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="#android:integer/config_shortAnimTime"
android:propertyName="rotation"
android:valueFrom="180"
android:valueTo="0"/>
And the vector that I'm transforming.
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<group
android:name="rotationGroup"
android:pivotX="12"
android:pivotY="12"
android:rotation="0.0">
<group
android:translateX="7.0"
android:translateY="9.0">
<path
android:fillColor="#color/sc_item_filter_list_chevron"
android:pathData="M 1,-4 L 1,4 L -1,4 L -1,-4 Z" />
</group>
</group>
</vector>
What is my problem:
When I click the button - I use the resource with an arrow pointing up. Then I animate it 180.0 degrees down.
When I click again - I switch to arrow pointing down and re-animate it back up to 0.0.
The bug I've encountered: When I tap the button between the animations (so for example when the arrow is at 90.0 degrees) the animations jumps to the beginning.
I tried using the <animated-selector> but I guess it didn't fix my problem. (or maybe it was me implementing it wrong)
I may switch to Property Animation, but it sounds like a lot of work. So before I do that - is there a better solution for this, using stuff I've showed you?

Android Animation ObjectAnimator Pivot from center

Another simple question that I can't seem to wrap my head around. I want an animation using ObjectAnimator to scale upwards from the center. However, I'm not sure how to set the PivotX/Y properties as any value I apply doesn't seem to affect the view. When I was using a scaleanimation, it worked fine but I must use an ObjectAnimator here.
I've tried
ObjectAnimator scaleX = ObjectAnimator.ofFloat(view,"scaleX",0.0f,1.0f);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(view,"scaleY",0.0f,1.0f);
//I've tried a wide range of values from 0,0 to 0,0.5, to 0.5, 0.5 but none of them do anything
ObjectAnimator pivotX = ObjectAnimator.ofFloat(view,"pivotX",0,1f);
ObjectAnimator pivotY = ObjectAnimator.ofFloat(view,"pivotY",0,1f);
//I've also tried view.setPivotX(0.5f) but that didn't do anything either
animatorSet.playTogether(scaleX,scaleY,pivotX,pivotY);
animatorSet.start();
I'm just not really sure how to make it scale from the center. I've tried not even using pivot but that didn't do anything either.
Any help is appreciated,
Thanks
** EDIT **
The following sort of works, except it isn't completely centered it instead grows towards the top left but still sort of centered. Its hard to describe. I tried using 0.5f and it didn't work either
ObjectAnimator pivotX = ObjectAnimator.ofFloat(view,"pivotX",1f);
ObjectAnimator pivotY = ObjectAnimator.ofFloat(view,"pivotY",1f);
I was having a similar problem scaling a vector animation defined in XML. It now scales from its center after placing the pivotX & pivotY settings in the Drawable instead of the ObjectAnimator, like so:
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt" >
<aapt:attr name="android:drawable">
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="100dp"
android:height="100dp"
android:viewportWidth="100"
android:viewportHeight="100">
<group
android:name="scaleGroup"
android:pivotX="50"
android:pivotY="50"
android:scaleX="1.0"
android:scaleY="1.0" >
<path
android:name="v"
android:strokeColor="#00e9bd"
android:strokeWidth="6"
android:pathData="M 50 13 C 70.4345357437 13 87 29.5654642563 87 50 C 87 70.4345357437 70.4345357437 87 50 87 C 29.5654642563 87 13 70.4345357437 13 50 C 13 29.5654642563 29.5654642563 13 50 13 Z" />
</group>
</vector>
</aapt:attr>
<target android:name="scaleGroup"> *
<aapt:attr name="android:animation">
<set>
<objectAnimator
android:duration="1000"
android:propertyName="scaleX"
android:valueFrom="0.5"
android:valueTo="1.0" />
<objectAnimator
android:duration="1000"
android:propertyName="scaleY"
android:valueFrom="0.5"
android:valueTo="1.0" />
</set>
</aapt:attr>
</target>
</animated-vector>
If you want to scale upwards one clear option is:
view.setPivotY(100);
and downwards:
view.setPivotY(0);
then animate.
pivotX and pivotY should be 1/2 the viewportWidth and viewportHeight respectively if you want to scale from the center.
These properties should be set on the group tag of your vector drawable. This group tag should be outside of the path tag that you want to scale, similar to the answer above.

Categories

Resources