ObjectAnimator how to reuse or continue animation with values - android

I am using ObjectAnimator to animate marker in google map but i want to reuse ObjectAnimator or continue the animation when new location is received i am using it like
public void onLocationUpdate(LatLong latLng)
{
ObjectAnimator animator =
ObjectAnimator.ofObject(marker, property, typeEvaluator,latLng);
animator.setDuration(1000);
animator.setInterpolator(new LinearInterpolator());
animator.setStartDelay(0);
animator.start();
animator.addListener(animatorEndListener);
}
i am getting this method called at the interval of 1 second i want to animate to have it appear continuous or at least reuse ObjectAnimator in case animation is finished when new value come so that it don,t create always new object

Related

How to start multiple ObjectAnimator on view simultaneously?

Here i am trying to move a view on a path with ObjectAnimator and also need to set one more scale animation on same view.
ObjectAnimator objectAnimator = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP)
{
objectAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
}
if (objectAnimator != null) {
objectAnimator.setDuration(2500);
objectAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
objectAnimator.start();
view.startAnimation(scaleRection);// this is not working because changing of x y position
need to start another Animation when objectAnimator.start();
also tried with listener
objectAnimator.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
view.startAnimation(scaleRection);
}
#Override
public void onAnimationEnd(Animator animation)
{
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
You can also use an AnimatorSet play together https://developer.android.com/reference/android/animation/AnimatorSet.html#playTogether and it's builder function https://developer.android.com/reference/android/animation/AnimatorSet.Builder
To play Two ObjectAnimator together
e.g.
AnimatorSet animationSet = new AnimatorSet();
ObjectAnimator scaleY = ObjectAnimator.ofFloat(view,"scaleY", 1f, 0f);
scaleY.setDuration(5000);
scaleY.setInterpolator(new AccelerateDecelerateInterpolator());
ObjectAnimator scaleX = ObjectAnimator.ofFloat(view,"scaleX", 1f, 0f);
scaleX.setDuration(5000);
scaleX.setInterpolator(new AccelerateDecelerateInterpolator());
animationSet.playTogether(scaleX, scaleY);
animationSet.start();
I would suggest using ViewPropertyAnimator.
From the docs :
This class enables automatic and optimized animation of select
properties on View objects. If only one or two properties on a View
object are being animated, then using an ObjectAnimator is fine; the
property setters called by ObjectAnimator are well equipped to do the
right thing to set the property and invalidate the view appropriately.
But if several properties are animated simultaneously, or if you just
want a more convenient syntax to animate a specific property, then
ViewPropertyAnimator might be more well-suited to the task.
This class may provide better performance for several simultaneous
animations, because it will optimize invalidate calls to take place
only once for several properties instead of each animated property
independently causing its own invalidation. Also, the syntax of using
this class could be easier to use because the caller need only tell
the View object which property to animate, and the value to animate
either to or by, and this class handles the details of configuring the
underlying Animator class and starting it.
You can chain as many animations as you like at once in one line of code :
view.animate().translationX(...).translationY(...).scaleX(...).scaleY(...).setInterpolator(new AccelerateDecelerateInterpolator()).setDuration(2500);
if you need different values for your duration or similar, you can do it with two lines :
view.animate().translationX().setDuration(...) ...
view.animate().scaleX().setDuration(...) ...
There are also methods translationXBy() and scaleXBy() which might be more suitable for your case, and you can also set a listener etc. Check the docs for all available methods

Bounce animation with depth

how i can add bounce animation to view which will go down and come up but it should do this only for one time .
if i set bounce interpolator with y its bouncing for given duration
but i want it for one time only but it should go say 5dp down and up to current view
ObjectAnimator animator = ObjectAnimator.ofFloat(targetView, "translationY", 0, 50, 0);
animator.setInterpolator(new BounceInterpolator());
animator.setDuration(200);
animator.start();
Use OvershootInterpolator.
Doc:
An interpolator where the change flings forward and overshoots the
last value then comes back.
You can adjust the tension of the overshoot using the constructor with tension parameter:
OvershootInterpolator(float tension)
tension: Amount of overshoot. When tension equals 0.0f, there is no
overshoot and the interpolator becomes a simple deceleration
interpolator.
Default value of tension is 2.0f.
Example using ViewPropertyAnimator:
targetView.animate()
.translationY(50)
.setInterpolator(new OvershootInterpolator())
.setDuration(200);
using ObjectAnimator:
ObjectAnimator animator = ObjectAnimator.ofFloat(targetView, "translationY", 0, 50); // pass only start and end values.
animator.setInterpolator(new OvershootInterpolator());
animator.setDuration(200);
animator.start();

How to use setDelay for animation within an AnimatorSet?

I'm trying to implement a set of animations, but the start delay value does not seem to be respected. Example:
ObjectAnimator a1 = ObjectAnimator.ofFloat(view1, View.ALPHA, 1f, 0f);
a1.setDuration(500);
a1.setStartDelay(500);
ObjectAnimator a2 = ObjectAnimator.ofFloat(view2, "translationX", ...);
a2.setDuration(500);
AnimatorSet set = new AnimatorSet();
set.playTogether(a1, a2);
set.start();
I can see the alpha animation starts immediately. If I don't try to play them together, the delay is respected and works fine. Can the delay not be used if part of an AnimatorSet?
If you want to play the animations in sequence, don't use ObjectAnimator.setStartDelay(). It's not designed for that use case.
Use AnimatorSet.playSequentially() instead:
AnimatorSet set = new AnimatorSet();
set.playSequentially(a2, a1);
set.start();

Infinite ObjectAnimator with interpolator... How to accelerate only the initial start?

I have a object animator with infinite repeat mode. I want to accelerate it only the first time it starts... not every time it is repeating itself
How can this be achieved?
my code:
universeMovement1 = ObjectAnimator.ofFloat(universeImageView, "x", 0, sw);
universeMovement1.setDuration(UNIVERSE_MOVEMENT_TIME);
universeMovement1.setRepeatCount(ObjectAnimator.INFINITE);
universeMovement1.setRepeatMode(ObjectAnimator.RESTART);
universeMovement1.setInterpolator(new AccelerateInterpolator());
Add a listener to your animation with the method onAnimationRepeat and set the interpolator back to LinearInterpolator, or whatever you want. Hence when it repeats it won't accelerate anymore.
animation.addListener(new AnimatorListenerAdapter(){
#Override
public void onAnimationRepeat(Animator animation) {
animation.setInterpolator(new LinearInterpolator());
}
});
use this:
objectAnimator.setInterpolator(new LinearInterpolator());

How to execute TranslateAnimation sequentially without knowing how many translate you'll have to do (android)?

The question is simple but i tried to search a solution in other similar questions, and i couldn't.
I have a arraylist path containing objects of type Coordinata that is an object containing two float X and Y, that is a coordinate. In substance, it's a list of coordinate. I need my ImageView image to move on a map on my view doing several subsequential TranslateTrasformation between the coordinate contained in the list path.
This can be easily done in the case of a fixed number of translation, doing the first translate and attaching it a setAnimationListener which could catch the end of the first animation and start in that moment the second and so on. I tried to iterate the process on my list path, using a while cycle, for i cannot really know how many coordinate will be in the path when the animation will start.
The result is the animation go on for the first couple of coordinates and then jump executing the animation for the last two coordinate in the path, ignoring all that is among these.
What is going on? I'm messing up with objects?
List<Coordinata> path; // properly filled with coordinates
Coordinata coordTempStart;
Coordinata coordTempArrival;
ImageView image;
ListIterator<Coordinata> pathIterator = path.listIterator();
if(pathIterator.hasNext()){
coordTempStart = (Coordinata) pathIterator.next();
}
if(pathIterator.hasNext()){
coordTempArrival = (Coordinata) pathIterator.next();
animation = new TranslateAnimation(coordTempStart.getX(),
coordTempArrival.getX(),
coordTempStart.getY(),
coordTempArrival.getY());
animation.setDuration(3000);
image.startAnimation(animation);
}
while(pathIterator.hasNext()){
coordTempStart=coordTempArrival;
coordTempArrival = (Coordinata) pathIterator.next();
animation.setAnimationListener(new TranslateAnimation.AnimationListener(){
public void onAnimationStart(Animation arg0) {}
public void onAnimationRepeat(Animation arg0) {}
public void onAnimationEnd(Animation arg0) {
animation = new TranslateAnimation(coordTempStart.getX(),
coordTempArrival.getX(),
coordTempStart.getY(),
coordTempArrival.getY());
animation.setDuration(3000);
image.startAnimation(animation);
}
});
}
I suggest to use ObjectAnimator and AnimatorSet to animate views. Object animator is available only for api > 11 but you can use NineOldAndroid if you have to keep the compatibility.
your code will be something like this (in pseudocode):
...
AnimatorSet animatorSet = new AnimatorSet();
while(pathIterator.hasNext()){
...
//Set _your_delta_x_ and _your_delta_y_ from iterator
...
ObjectAnimator xTrasnlationObjectAnimator = ObjectAnimator.ofFloat(v, view_x, _your_delta_x_);
ObjectAnimator yTrasnlationObjectAnimator = ObjectAnimator.ofFloat(v, view_y, _your_delta_y_);
animatorSet.playSequentially(xTrasnlationObjectAnimator, yTrasnlationObjectAnimator);
}
...
animatorSet.start()
to set right parameters to object animator refer the official documentation http://developer.android.com/reference/android/animation/ObjectAnimator.html
Just for the sake of completeness, i publish the actual code used to solve the problem:
// in this list you can insert as many animations you want
List<Animator> animations = new ArrayList<Animator>();
AnimatorSet animatorSet = new AnimatorSet();
ObjectAnimator xTrasnlationObjectAnimator = ObjectAnimator.ofFloat(image, View.TRANSLATION_X, (float)300);
xTrasnlationObjectAnimator.setRepeatCount(0);
ObjectAnimator yTrasnlationObjectAnimator = ObjectAnimator.ofFloat(image, View.TRANSLATION_Y, (float)300);
yTrasnlationObjectAnimator.setRepeatCount(0);
ObjectAnimator x2TrasnlationObjectAnimator = ObjectAnimator.ofFloat(image, View.TRANSLATION_X, (float)400);
x2TrasnlationObjectAnimator.setRepeatCount(0);
animations.add(xTrasnlationObjectAnimator);
animations.add(yTrasnlationObjectAnimator);
animations.add(x2TrasnlationObjectAnimator);
animatorSet.playSequentially(animations);
animatorSet.start();

Categories

Resources