I have this xml code, that should simulate a sort of "heart beat" animation. Image that use it should scale twice, and return to original size, then restart again:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:repeatCount="-1"
android:repeatMode="restart"
android:shareInterpolator="true" >
<scale
android:duration="500"
android:fromXScale="1"
android:fromYScale="1"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.2"
android:toYScale="1.2" />
<scale
android:duration="500"
android:fromXScale="1.2"
android:fromYScale="1.2"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.4"
android:toYScale="1.4" />
<scale
android:duration="500"
android:fromXScale="1.4"
android:fromYScale="1.4"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.0"
android:toYScale="1.0" />
</set>
and this is how i add this animation set to my imageview:
AnimationSet heart_pulse = new AnimationSet(true);
heart_pulse.addAnimation(AnimationUtils.loadAnimation(activity,
R.anim.pulsexml));
logo.setAnimation(heart_pulse);
logo.startAnimation(heart_pulse);
but animation is executed only one time, then it stops. Why?
try this custom Interpolator:
final ImageView iv = new ImageView(this);
iv.setImageResource(R.drawable.heart);
setContentView(iv);
Runnable action = new Runnable() {
#Override
public void run() {
Interpolator i = new Interpolator() {
#Override
public float getInterpolation(float input) {
float x = input < 1/3f? 2 * input : (1 + input) / 2;
return (float) Math.sin(x * Math.PI);
}
};
ScaleAnimation anim = new ScaleAnimation(1, 1.2f, 1, 1.2f, iv.getWidth() / 2, iv.getHeight() / 2);
anim.setRepeatCount(Animation.INFINITE);
anim.setDuration(750);
anim.setInterpolator(i);
iv.startAnimation(anim);
}
};
iv.post(action);
Have you tried adding android:fillAfter="false"?
EDIT:
According to the documentation sintax of Animation, these properties must be set to an Animatior and not to the set, so let's have then this custom animation repeating with no code:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:duration="500"
android:fromXScale="1"
android:fromYScale="1"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="-1"
android:repeatMode="restart"
android:toXScale="1.2"
android:toYScale="1.2" />
<scale
android:duration="500"
android:fromXScale="1.2"
android:fromYScale="1.2"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="-1"
android:repeatMode="restart"
android:toXScale="1.4"
android:toYScale="1.4" />
<scale
android:duration="500"
android:fromXScale="1.4"
android:fromYScale="1.4"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="-1"
android:repeatMode="restart"
android:toXScale="1.0"
android:toYScale="1.0" />
</set>
Consider using a CycleInterpolator for your animation, e.g.:
final Animation animation = AnimationUtils.loadAnimation(context, R.anim.pulsexml);
animation.setInterpolator(new CycleInterpolator(3f));
logo.startAnimation(animation);
Related
I am trying to do an animation on an imageview, were i need to scale up and scale down the image so that it will have a shadow feel effect for another animation.
I tried adding two xml in anim folder -
scale_up.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator"
android:shareInterpolator="false">
<scale
android:duration="1250"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:repeatMode="restart"
android:toXScale="1.5"
android:toYScale="1.5" />
</set>
scale_down.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator"
android:shareInterpolator="false">
<scale
android:duration="1250"
android:fromXScale="1.5"
android:fromYScale="1.5"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:repeatMode="restart"
android:toXScale="1.0"
android:toYScale="1.0" />
</set>
and in my activity class
AnimationSet s = new AnimationSet(false);
View shadowView = view.findViewById(R.id.shadowView);
final Animation scaleDownAnimation = AnimationUtils.loadAnimation(context, R.anim.scale_down);
final Animation scaleUpAnimation = AnimationUtils.loadAnimation(context, R.anim.scale_up);
s.addAnimation(scaleUpAnimation);
s.addAnimation(scaleDownAnimation);
shadowView.startAnimation(s);
But animation is not happening. What i am doing wrong? Anyone please help. Thanks
AnimationSet performs animation simultanuously, not sequentaly by default. So it does zoom in and zoom out at the same time. That's why you see no effect. But you can set a start offset to the animation:
AnimationSet s = new AnimationSet(false);
View shadowView = view.findViewById(R.id.shadowView);
final Animation scaleDownAnimation = AnimationUtils.loadAnimation(context, R.anim.scale_down);
final Animation scaleUpAnimation = AnimationUtils.loadAnimation(context, R.anim.scale_up);
scaleDownAnimation.setStartOffset(1250); //this line
s.addAnimation(scaleUpAnimation);
s.addAnimation(scaleDownAnimation);
shadowView.startAnimation(s
Hey I have the following problem whan I animate my floating buttons - namely they are scaling badly. First of all, fab buttons on the second Image are higher than they should. Event main floating button with "+" is not rotating. I anyone know how to deal with it please answer me.
Image left HTC One MAX, screen HD - SKD21 lolipop, emulator 768x1280 SKD 17 jelly bean
my code in Activity.PhotoGallery
private void showFabs(){
Animation show_fab_photo = AnimationUtils.loadAnimation(getApplication(), R.anim.fab_add_photo_show);
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) fabAddPhoto.getLayoutParams();
layoutParams.bottomMargin += (int) (fabAddPhoto.getHeight() * 1.7);
fabAddPhoto.setLayoutParams(layoutParams);
fabAddPhoto.startAnimation(show_fab_photo);
fabAddPhoto.setClickable(true);
Animation show_fab_gallery = AnimationUtils.loadAnimation(getApplication(), R.anim.fab_add_from_gallery_show);
FrameLayout.LayoutParams layoutParamsGallery = (FrameLayout.LayoutParams) fabAddFromGallery.getLayoutParams();
layoutParamsGallery.bottomMargin += (int) (fabAddFromGallery.getHeight() * 3.4);
fabAddFromGallery.setLayoutParams(layoutParamsGallery);
fabAddFromGallery.startAnimation(show_fab_gallery);
fabAddFromGallery.setClickable(true);
Animation rotateFabAdd = AnimationUtils.loadAnimation(getApplication(), R.anim.fab_gallery_show);
fabAdd.startAnimation(rotateFabAdd);
}
private void hideFabs(){
Animation hide_fab_photo = AnimationUtils.loadAnimation(getApplication(), R.anim.fab_add_photo_hide);
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) fabAddPhoto.getLayoutParams();
layoutParams.bottomMargin -= (int) (fabAddPhoto.getHeight() * 1.7);
fabAddPhoto.setLayoutParams(layoutParams);
fabAddPhoto.startAnimation(hide_fab_photo);
fabAddPhoto.setClickable(false);
Animation hide_fab_gallery = AnimationUtils.loadAnimation(getApplication(), R.anim.fab_add_from_gallery_hide);
FrameLayout.LayoutParams layoutParamsGallery = (FrameLayout.LayoutParams) fabAddFromGallery.getLayoutParams();
layoutParamsGallery.bottomMargin -= (int) (fabAddFromGallery.getHeight() * 3.4);
fabAddFromGallery.setLayoutParams(layoutParamsGallery);
fabAddFromGallery.startAnimation(hide_fab_gallery);
fabAddFromGallery.setClickable(false);
Animation rotateFabAdd = AnimationUtils.loadAnimation(getApplication(), R.anim.fab_gallery_hide);
fabAdd.startAnimation(rotateFabAdd);
}
And my animations XML files
Fab with camera
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<!-- Rotate -->
<rotate
android:duration="500"
android:fromDegrees="30"
android:interpolator="#android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="0"
android:repeatMode="reverse"
android:toDegrees="0"></rotate>
<!--Move-->
<translate
android:duration="800"
android:fromXDelta="0%"
android:fromYDelta="170%"
android:interpolator="#android:anim/linear_interpolator"
android:toXDelta="0%"
android:toYDelta="0%"></translate>
<!--Fade In-->
<alpha
android:duration="1500"
android:fromAlpha="0.0"
android:interpolator="#android:anim/decelerate_interpolator"
android:toAlpha="1.0"></alpha>
</set>
Fab with image
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<!-- Rotate -->
<rotate
android:duration="500"
android:fromDegrees="30"
android:interpolator="#android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="0"
android:repeatMode="reverse"
android:toDegrees="0"></rotate>
<!--Move-->
<translate
android:duration="800"
android:fromXDelta="0%"
android:fromYDelta="340%"
android:interpolator="#android:anim/linear_interpolator"
android:toXDelta="0%"
android:toYDelta="0%"></translate>
<!--Fade In-->
<alpha
android:duration="1500"
android:fromAlpha="0.0"
android:interpolator="#android:anim/decelerate_interpolator"
android:toAlpha="1.0"></alpha>
</set>
In my application I have this animation
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"
android:shareInterpolator="true">
<alpha
android:duration="1000"
android:startOffset="2000"
android:fromAlpha="0"
android:toAlpha="1"/>
<scale
android:duration="400"
android:startOffset="4000"
android:fromXScale="1"
android:fromYScale="1"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="0.9"
android:toYScale="0.9"/>
<scale
android:duration="400"
android:startOffset="4400"
android:fromXScale="0.9"
android:fromYScale="0.9"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1"
android:toYScale="1"/>
<alpha
android:duration="1000"
android:startOffset="5800"
android:fromAlpha="1"
android:toAlpha="0"/>
</set>
Generally it shows image, make "press" gesture and hide it. What I want is run this animation in infinite loop. Setting parameter repeatCount doesn't work. Only way I found is to start animation again in animation listener.
final Animation pointerAnim = AnimationUtils.loadAnimation(this, R.anim.pointer);
pointerAnim.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(final Animation animation) {}
#Override
public void onAnimationEnd(final Animation animation) {
pointerView.startAnimation(pointerAnim);
}
#Override
public void onAnimationRepeat(final Animation animation) {}
});
pointerView.startAnimation(pointerAnim);
But here comes my problem. Between end and new start animation, the image "blink" (appeared and disappeared in short moment) and I don't know how to prevent this. Using fillAfter doesn't work. Also setting appropriate visibility in listener doesn't work. Note that target API is 10.
I'll be glad for any advice
This was surprisingly tricky, but here's an answer that seems to work and avoid the blinking. Break the animation up into two parts and set two animation listeners so that when each of them finish, they trigger the other one to start. It looks as follows:
pointer_fade_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"
android:shareInterpolator="true">
<alpha
android:duration="1000"
android:startOffset="2000"
android:fromAlpha="0"
android:toAlpha="1"/>
<scale
android:duration="400"
android:startOffset="4000"
android:fromXScale="1"
android:fromYScale="1"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="0.9"
android:toYScale="0.9"/>
</set>
pointer_fade_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:duration="400"
android:startOffset="0"
android:fromXScale="0.9"
android:fromYScale="0.9"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1"
android:toYScale="1"/>
<alpha
android:duration="1000"
android:startOffset="1400"
android:fromAlpha="1"
android:toAlpha="0"/>
</set>
Then the code:
final Animation pointerFadeInAnim = AnimationUtils.loadAnimation(this, R.anim.pointer_fade_in);
final Animation pointerFadeOutAnim = AnimationUtils.loadAnimation(this, R.anim.pointer_fade_out);
pointerFadeInAnim.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(final Animation animation) {}
#Override
public void onAnimationEnd(final Animation animation) {
pointerView.startAnimation(pointerFadeOutAnim);
}
#Override
public void onAnimationRepeat(final Animation animation) {}
});
pointerFadeOutAnim.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation) {
pointerView.startAnimation(pointerFadeInAnim);
}
#Override
public void onAnimationRepeat(Animation animation) {}
});
pointerView.startAnimation(pointerFadeInAnim);
Hope this works for you!
Did you try combining both repeatMode and repeatCount attributes like in the following example
<scale
android:fromXScale="0.0"
android:toXScale="1.0"
android:fromYScale="0.0"
android:toYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000"
android:repeatCount="infinite"
android:repeatMode="restart"
/>
Hope it has helped
Maybe it's just a workaround that won't be applicable in your case, but would it be possible to offset the entiere animation, so that it starts at 3000 ? (Thus, when alpha=1.0)
(Well, after some thought, I'm pretty sure you can't do that, because the alpha transition should be the first when the object first appears on screen)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"
android:shareInterpolator="true">
<scale
android:duration="400"
android:startOffset="1000"
android:fromXScale="1"
android:fromYScale="1"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="0.9"
android:toYScale="0.9"/>
<scale
android:duration="400"
android:startOffset="1400"
android:fromXScale="0.9"
android:fromYScale="0.9"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1"
android:toYScale="1"/>
<alpha
android:duration="1000"
android:startOffset="2800"
android:fromAlpha="1"
android:toAlpha="0"/>
<alpha
android:duration="1000"
android:startOffset="5800"
android:fromAlpha="0"
android:toAlpha="1"/>
</set>
I have problem with scale in animation. Translate works fine, but when I add scale to my animation it dont come back to point of start and blink when animation starts again.
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator">
<translate
android:fromYDelta="-150"
android:toYDelta="150"
android:fillAfter="true"
android:duration="1500"
/>
<scale
android:fillAfter="true"
android:fromXScale="1"
android:fromYScale="1"
android:toXScale="1.2"
android:toYScale="1.2"
android:duration="1500"
android:pivotX="50%"
android:pivotY="50%"
/>
</set>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator">
<translate
android:fromYDelta="150"
android:toYDelta="-150"
android:fillAfter="true"
android:duration="1500"
android:startOffset="1500"
/>
<scale
android:fillAfter="true"
android:fromXScale="1.2"
android:fromYScale="1.2"
android:toXScale="1"
android:toYScale="1"
android:duration="1500"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="1500"
/>
</set>
And Android code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image = (ImageView) findViewById(R.id.image);
image.setImageResource(R.drawable.shape);
animation2 = AnimationUtils.loadAnimation(this, R.anim.moving_up);
animation3 = AnimationUtils.loadAnimation(this, R.anim.moving_down);
animation = new AnimationSet(true);
animation.addAnimation(animation2);
animation.addAnimation(animation3);
animation.setAnimationListener(this);
//animation.setRepeatCount(Animation.INFINITE);
animation.setFillEnabled(true);
animation.setFillAfter(true);
image.startAnimation(this.animation);
}
#Override
public void onAnimationEnd(Animation animation) {
image.clearAnimation();
image.startAnimation(animation);
}
Shape is a xml Rect.
animation.setFillAfter(true);
will force the image to stay at animated position after animation gets completed.
Set it to false if you want to return the image to starting position.
animation.setFillAfter(false);
If someone would like to know the answer
private void animateImage(){
float x = 1;
float scale = 1.1f;
x = (imageViewImage.getHeight()*1.1f - imageViewImage.getHeight())/2;
imageViewImage.animate().translationY(x).scaleX(scale).scaleY(scale).setDuration(8000).withEndAction(new Runnable() {
#Override
public void run() {
imageViewImage.animate().translationY(0).scaleX(1f).scaleY(1f).setDuration(8000).withEndAction(new Runnable() {
#Override
public void run() {
animateImage();
}
});
}
});
}
How can I add animation to DialogFragment. My animations are:
out anim:
<scale
android:duration="200"
android:fillAfter="false"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:interpolator="#android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="-90%"
android:startOffset="200"
android:toXScale="0.5"
android:toYScale="0.5" />
<translate
android:duration="300"
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="-200"
android:toYDelta="-200" />
in anim:
<scale
android:duration="200"
android:fillAfter="false"
android:fromXScale="0.5"
android:fromYScale="0.5"
android:interpolator="#android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="-90%"
android:toXScale="1.0"
android:toYScale="1.0" />
<translate
android:duration="300"
android:fromXDelta="-200"
android:fromYDelta="-200"
android:toXDelta="0"
android:toYDelta="0" />
and my code:
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.jump_in, R.anim.jump_out, R.anim.jump_in, R.anim.jump_out);
ft.add(layer_frag, "layer frag");
ft.show(layer_frag).commit();//layer_frag is a class whitch extends DialogFragment
I must miss something because it appears as it appears before.
#Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
final Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.getWindow().getAttributes().windowAnimations = R.style.detailDialogAnimation;
return dialog;
}
The answer was from stackoverflow.com/a/13537234/969325 but You have to set the style at onCreateDialog function.