I need to slow down an rotate animation over an imageview: it begin faster, then it should "decelerate" until end of animation (then rotation stop). I've write this:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<rotate
android:duration="100"
android:fromDegrees="0"
android:interpolator="#android:anim/cycle_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="30"
android:repeatMode="restart"
android:toDegrees="360" />
</set>
then add listener to animation:
Animation rotate = AnimationUtils
.loadAnimation(activity, R.anim.rotate);
ImageView logo = (ImageView) SplashScreen.activity
.findViewById(R.id.logo);
rotate.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animation animation) {
Intent intent = new Intent(SplashScreen.this,
LoginActivity.class);
SplashScreen.this.startActivity(intent);
}
#Override
public void onAnimationRepeat(Animation animation) {
if(animation.getRepeatCount() == 5) {
animation.setDuration(200);
} else if (animation.getRepeatCount() == 10) {
Log.i("ANIM", "10");
animation.setDuration(5000);
} else if (animation.getRepeatCount() == 15) {
animation.setDuration(800);
} else if (animation.getRepeatCount() == 20) {
animation.setDuration(1600);
} else if (animation.getRepeatCount() == 25) {
animation.setDuration(2000);
}
}
});
logo.setAnimation(rotate);
logo.startAnimation(rotate);
but animation has always the same velocity (code never go into onAnimationRepeat). What's wrong?
Simply use
android:interpolator="#android:anim/decelerate_interpolator"
in your animation xml file.
check this link for other interpolators http://developer.android.com/reference/android/view/animation/package-summary.html
also add
android:repeatCount="1"
because the default is 0.
Try this :
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<rotate
android:duration="100"
android:fromDegrees="0"
android:interpolator="#android:anim/decelerate_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="30"
android:repeatMode="restart"
android:toDegrees="360" />
</set>
Change interpolator cycle_interpolator to decelerate_interpolator so that you get an effect which is faster at beginning and gradually slows down.
Related
Following is my zoom_in.xml
<set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true" >
<scale
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromXScale="0"
android:fromYScale="0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1"
android:toYScale="1" >
</scale>
</set>
the view is zoom in three time. how I can make it to only one time
PS: android:repeatCount="1" is not working.
EDIT 1: my animation Util have Load animation as folowing
public static Animation loadAnimation(Context context, #AnimRes int id)
throws NotFoundException {
XmlResourceParser parser = null;
try {
parser = context.getResources().getAnimation(id);
return createAnimationFromXml(context, parser);
} catch (XmlPullParserException ex) {
NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
Integer.toHexString(id));
rnf.initCause(ex);
throw rnf;
} catch (IOException ex) {
NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
Integer.toHexString(id));
rnf.initCause(ex);
throw rnf;
} finally {
if (parser != null) parser.close();
}
now I have called it as following
zoomIn = loadAnimation(getContext(),
R.anim.zoom_in);
view.startAnimation(zoomIn);
Set repeat count to 0
zoomIn = loadAnimation(getContext(), R.anim.zoom_in);
zoomIn.setRepeatCount(0);
Add AnimationListener to zoomIn like below
zoomIn.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
// clear animation here
view.clearAnimation();
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
Hope this will help.
Insted of using "set" try "objectAnimator" :
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromXScale="0"
android:fromYScale="0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1"
android:toYScale="1"
android:repeatCount="1" />
i am trying to scale an image, rotate it, rotate it backwards and then scale it to its origninal size.
This is allready working, but i cant figure out how to repeat this animation set infinitly ( android:repeatCount="infinite" isnt working for me ).
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
android:shareInterpolator="true"
android:repeatCount="infinite"
>
<scale
android:fromXScale="1.0"
android:toXScale="4.0"
android:fromYScale="1.0"
android:toYScale="4.0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="700"
/>
<rotate
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="700"
android:duration="2000"
/>
<rotate
android:fromDegrees="360"
android:toDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="2700"
android:duration="2000"
/>
<scale
android:fromXScale="1.0"
android:toXScale="0.25"
android:fromYScale="1.0"
android:toYScale="0.25"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="4700"
android:duration="700"
/>
</set>
and in the Activity:
ImageView imageView = (ImageView) findViewById(R.id.imageView2);
Animation rotateAndScale = AnimationUtils.loadAnimation(this, R.anim.rotate_z);
imageView.startAnimation(rotateAndScale);
<set> marker in xml is bad implemented and not work propperly. Full explenation here: Android animation does not repeat
what you should do is use listener and method to use recurency to roll the anim for ever.
public void startAnimation() {
View component= findViewById(R.id.imageView2);
component.setVisibility(View.VISIBLE);
Animation anim = AnimationUtils.loadAnimation(this, R.anim.rotate_z);
anim.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationEnd(Animation arg0) {
Animation anim = AnimationUtils.loadAnimation(this, R.anim.rotate_z);
anim.setAnimationListener(this);
component.startAnimation(anim);
}
#Override
public void onAnimationRepeat(Animation arg0) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationStart(Animation arg0) {
// TODO Auto-generated method stub
}
});
component.startAnimation(anim);
}
I've succesfully managed to do a nice slide-down effect when expanding a list-object by using an animation. I am trying to do the reverse thing, a slide-up effect, when collapsing the expanded view, but with no success. Here is my onclicklistener:
head.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (child.isShown()) {
Slide.slide_up(Kalender.this, child);
child.setVisibility(View.GONE);
} else {
child.setVisibility(View.VISIBLE);
Slide.slide_down(Kalender.this, child);
}
}
});
And my Slide-class:
public class Slide {
public static void slide_down(Context context, View view) {
Animation anim = AnimationUtils.loadAnimation(context, R.anim.slide_down);
if (anim != null) {
anim.reset();
if (view != null) {
view.clearAnimation();
view.startAnimation(anim);
}
}
}
public static void slide_up(Context context, View view) {
Animation anim = AnimationUtils.loadAnimation(context, R.anim.slide_up);
if (anim != null) {
anim.reset();
if (view != null) {
view.clearAnimation();
view.startAnimation(anim);
}
}
}
And finally the animations. Slide-down:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true" >
<scale
android:duration="200"
android:fromXScale="1.0"
android:fromYScale="0.0"
android:interpolator="#android:anim/linear_interpolator"
android:toXScale="1.0"
android:toYScale="1.0" />
</set>
Slide-up:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true" >
<scale
android:duration="200"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:interpolator="#android:anim/linear_interpolator"
android:toXScale="1.0"
android:toYScale="0.0" />
</set>
The only difference is that the slide-down starts at y=0 and goes to y=1, and the slide-up starts at y=1 and goes back to y=0, but this seems to be the wrong way of doing it. How can I make the slide-up work as well? Thanks
I have an ImageView. I want to:
1 - shrink the view
2 - change the image resource
3 - scale back the view
I tried to this in the following section of code, but this is not working. It behaves like the 3rd row doesn't exist. Can someone tell me what I'm doing wrong?
Animation anim = AnimationUtils.loadAnimation(this, R.anim.scale);
Animation animo = AnimationUtils.loadAnimation(this, R.anim.scale_out);
i.startAnimation(anim);
i.setImageResource(R.drawable.logoc);
i.startAnimation(animo);
scale.xml:
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="1.0"
android:toXScale="0.125"
android:fromYScale="1.0"
android:toYScale="0.125"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="0"
android:duration="400"
android:fillBefore="true" />
scale_out.xml:
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="1.0"
android:toXScale="4.0"
android:fromYScale="1"
android:toYScale="4.0"
android:startOffset="400"
android:pivotX="50%"
android:pivotY="50%"
android:duration="800"
/>
I think you should try doing this way:
i.startAnimation(anim);
if (anim.hasEnded())
{
i.setImageResource(R.drawable.logoc);
i.startAnimation(animo);
}
Edit:
Ok, I was wrong: This works:
public class MyAnimationListener implements AnimationListener {
#Override
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
i.setImageResource(R.drawable.bg);
i.startAnimation(animo);
}
#Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
}
MyAnimationListener mListener = new MyAnimationListener();
anim.setAnimationListener(mListener);
i.startAnimation(anim);
I am using following code to rotate image view
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<rotate
android:fromDegrees="0"
android:toDegrees="360"
android:duration="500"
android:repeatCount="infinite"
android:pivotX="50%"
android:pivotY="50%"
>
</rotate>
</set>
Animation rotate1 = AnimationUtils.loadAnimation(this, R.anim.rotate_picture);
rotate.startAnimation(rotate1);
The Layout which I am using is:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/loader"
android:layout_centerInParent="true"
android:id="#+id/rotate"
/>
</RelativeLayout>
But it is stop 500ms and restarting again. But I need to rotate image continuously. Without stopping it in middle. How can I do this?
//custom_anim.xml
<?xml version="1.0" encoding="utf-8" ?>
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<rotate
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000" />
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="2000">
</alpha>
<scale
android:pivotX="50%"
android:pivotY="50%"
android:fromXScale=".1"
android:fromYScale=".1"
android:toXScale="1.0"
android:toYScale="1.0"
android:duration="2000" />
</set>
//Oncreate
Animation rotateimage = AnimationUtils.loadAnimation(this, R.anim.custom_anim);
imgageview.startAnimation(rotateimage);
rotateimage.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
AnimateandSlideShow();
}
});
//function
private void AnimateandSlideShow() {
Animation rotateimage = AnimationUtils.loadAnimation(this, R.anim.custom_anim);
imgageview.startAnimation(rotateimage);
rotateimage.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
AnimateandSlideShow();
}
});
}
I just tried it. For some odd reason it uses the AccelerateDecelerateInterpolator as default. Add android:interpolator="#android:anim/linear_interpolator" and you will get something more useful.
However there is still a tiny stop after every 500ms, I think it reloads the animation or it has one frame too much (0 = 360)
You can increase the values for a longer duration to get a better effect. Try android:duration="50000" and android:toDegrees="36000".
Add this property in rotate attribute
android:repeatMode="restart"
Or change your rotate1.xml file, remove set tag. Like this:
<rotate
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="360"
android:duration="500"
android:repeatCount="infinite"
android:pivotX="50%"
android:pivotY="50%">
</rotate>