Using Rotate Animation in android, but no rotation in image after clicking the button.
public class MainActivity extends AppCompatActivity {
ImageView spinImage;
Button buton;
Random r;
int degree =0 , degreeold= 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buton = (Button) findViewById(R.id.spinbutton);
spinImage= (ImageView) findViewById(R.id.spinimage);
r= new Random();
buton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
degreeold = degree % 360;
degree = r.nextInt(3600)+720;
degree= 4400;
RotateAnimation rotate = new RotateAnimation( degreeold, degree,
RotateAnimation.RELATIVE_TO_SELF,0.5f,RotateAnimation.RELATIVE_TO_SELF , 0.5f);
rotate.setDuration(3600);
rotate.setFillAfter(true);
rotate.setInterpolator( new DecelerateInterpolator());
rotate.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
spinImage.setAnimation(rotate);
}
});
}
i am not able to find the mistake why there is no rotation in image. there is no error while running and app open without any delay but there is no animation when clicking the button.
You haven't started the animation. Try to use spinImage.startAnimation(rotate);
setAnimation is meant to give you more fine grained control if you want to start the animation delayed or together with other animations.
From the documentation:
Sets the next animation to play for this view. If you want the animation to play immediately, use startAnimation(android.view.animation.Animation) instead. This method provides allows fine-grained control over the start time and invalidation, but you must make sure that 1) the animation has a start time set, and 2) the view's parent (which controls animations on its children) will be invalidated when the animation is supposed to start.
Replace spinImage.setAnimation(rotate); with spinImage.startAnimation(rotate);
I have an image in image view of my activity. There is button also in my activity. i want that when i press button image should be jump and rotate and will replace by another image. Actually i want to implement coin Toss application ?how can i achieve this . any help will be appreciated.
With ObjectAnimator and setting KeyFrame it can be achived, which was introduced in API 11.
You can use AnimationSet with animation listeners like:
AnimationSet aset= new AnimationSet();
aset.add(jumAnimation);
aset.add(flipAnimation1);
aset.add(flipAnimation2);
with flipAnimation1 rotate the view from 0 degrees to 90 degrees and change the image
then start the second animation and do the rest of the rotation.
flipAnimation.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animation animation) {
//change the image
//start flipAnimation2
}
});
});
imageView.startAnimation(aset);
Dont forget to set animation attributes like: duration,fillAfter.
I have an ImageButton in android which rotates when clicked. The issue is it does not finish rotating when the user taps it and proceeds to the new Activity on the next line. I have tried Thread.sleep(..) and wait(..) but putting RotateAnimation(..) along with these actually sleeps before the animation starts.
I need the animation to actually finish and then proceed to the startActivity(new Intent(..))
Here's the code
amazingPicsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
amazingPicsSound = createRandButSound();
amazingPicsSound.start();
rotateAnimation(v);
startActivity(new Intent("com.jasfiddle.AmazingInterface.AMAZINGPICS"));
}
});
}
/** function that produces rotation animation on the View v.
* Could be applied to button, ImageView, ImageButton, etc.
*/
public void rotateAnimation(View v){
// Create an animation instance
Animation an = new RotateAnimation(30, 360, v.getWidth()/2, v.getHeight()/2);
// Set the animation's parameters
an.setDuration(20); // duration in ms
an.setRepeatCount(10); // -1 = infinite repeated
// an.setRepeatMode(Animation.REVERSE); // reverses each repeat
an.setFillAfter(true); // keep rotation after animation
v.setAnimation(an);
// Apply animation to the View
}
Animation is an asynchronous process, therefore if you want animation to finish before proceeding, then you need to add animation listener and execute your next line of code when the animation completes:
amazingPicsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
amazingPicsSound = createRandButSound();
amazingPicsSound.start();
rotateAnimation(v);
}
});
and then
public void rotateAnimation(View v){
// Create an animation instance
Animation an = new RotateAnimation(30, 360, v.getWidth()/2, v.getHeight()/2);
// Set the animation's parameters
an.setDuration(20); // duration in ms
an.setRepeatCount(10); // -1 = infinite repeated
// an.setRepeatMode(Animation.REVERSE); // reverses each repeat
an.setFillAfter(true); // keep rotation after animation
an.addAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation) {
startActivity(new Intent("com.jasfiddle.AmazingInterface.AMAZINGPICS"));
}
});
v.setAnimation(an);
}
Note that startActivity call is not inside the onAnimationEnd method of the AnimationListener instead of being after setting the animation onto the view.
You never ask to your app to wait the end of the animation to start the new activity.
See http://developer.android.com/reference/android/view/animation/Animation.html#setAnimationListener(android.view.animation.Animation.AnimationListener)
to learn how use AnimationListener
I've seen all sorts of code that makes me think that mine should work, but for some reason it does not. I've got an ImageView that animates vertically down another image and I want the mobile imageview to disappear once the animation is complete but it does not. The 'scanbar' imageview is the one in question. it is set as invisible in the XML and is made visible on a button press. I need it to go away when the animation is finished.
public class scan extends Activity {
EditText Quote;
private static final Random rgenerator = new Random();
ImageView scanbar;
public void scanLine() {
// Displays the scanline animation over the wireframe image
ImageView wireframe;
scanbar = (ImageView)findViewById(R.id.scanbar);
wireframe = (ImageView) findViewById(R.id.wireframe);
scanbar.setVisibility(View.VISIBLE);
// Super ultra-secret code
}
Animation.AnimationListener scanListener = new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
scanbar.setVisibility(View.INVISIBLE);
setResults();
}
};
The setResults(); call works properly, so I know that section of code is being executed. Anyone know what I'm doing wrong?
Will give this old question an answer just in case someone stumbles upon it like me.
Check out stickupkid's answer here: Android, setVisbility to gone not working in RelativeLayout. Call clearAnimation() on what ever view is doing the animation before calling View.INVISIBLE
I can confirm that: Calling clearAnimation() on the view that is doing the animation before calling View.INVISIBLE, or GONE does the trick.
It seems that an android animation is not truly finished when the onAnimationEnd event is fired although animation.hasEnded is set to true.
I want my view to change it's background drawable on the end of it's ScaleAnimation which it does, but you can clearly see that it is changed some miliseconds before it finishes. The problem is, that it flickers because the new background appears (=is) scaled for a short time until the animation really finishes.
Is there a way to get either the real end of the animation or just prevent the new background from beeing scaled this short period of time?
Thank you!
//EDIT: I'm using an AnimationListener to get the following call:
#Override
public void onAnimationEnd(Animation animation)
{
View view = (MyView) ((ExtendedScaleAnimation) animation).getView();
view.clearAnimation();
view.requestLayout();
view.refreshBackground(); // <-- this is where the background gets changed
}
Here is the actual bug related to this issue http://code.google.com/p/android-misc-widgets/issues/detail?id=8
This basically states that the onAnimationEnd method doesn't really work well when an AnimationListener is attached to an Animation
The workaround is to listen for the animation events in the view to which you were applying the animation to
For example if initially you were attaching the animation listener to the animation like this
mAnimation.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationEnd(Animation arg0) {
//Functionality here
}
});
and then applying to the animation to a ImageView like this
mImageView.startAnimation(mAnimation);
To work around this issue, you must now create a custom ImageView
public class MyImageView extends ImageView {
and then override the onAnimationEnd method of the View class and provide all the functionality there
#Override
protected void onAnimationEnd() {
super.onAnimationEnd();
//Functionality here
}
This is the proper workaround for this issue, provide the functionality in the over-riden View -> onAnimationEnd method as opposed to the onAnimationEnd method of the AnimationListener attached to the Animation.
This works properly and there is no longer any flicker towards the end of the animation.
I was abe to resolve this by calling clearAnimation() on the view being animated inside onAnimationEnd, that took away the flicker
Its weird why would anyone have to do that, as onAnimationEnd callback should have been called only if the animation has already ended. But I guess the answer lies in the depth of Framework on how view/layout handles animation callback.
For now take it as a hack-free solution, that just works.
animation.setAnimationListener(new AnimationListener() {
public void onAnimationEnd(Animation anim) {
innerView.clearAnimation(); // to get rid of flicker at end of animation
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams
(innerBlockContainer.getWidth(), innerBlockContainer.getHeight());
/* Update lp margin, left/top to update layout after end of Translation */
ViewGroup parent_ofInnerView = (ViewGroup)innerView.getParent();
vp.updateViewLayout(innerBlockContainer, lp);
}
public void onAnimationRepeat(Animation arg0) {}
public void onAnimationStart(Animation arg0) {
}
});
innerView.startAnimation(animation);
I had same issue and solved it using
view.clearAnimation();
before
view.startAnimation(anim);
I had a similar problem and I used Soham's solution with custom view class.
It worked fine, but at the end, I've found a simpler solution that worked for me.
After calling the view.StartAnimation(animation), and before the next step in my program, I've added a short delay that will be long enough to let the animation finish, but short enough to be unnoticeable by the user:
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
nextStepInMyProgram();
}
}, 200);// delay in milliseconds (200)
For some reason the onAnimationStart works properly, and the onAnimationEnd doesnt. So heres how I originally did it and what I changed:
Attempt 1 (flicker):
a) Move image from 0px to 80px
b) In onAnimationEnd, set the image's location to 80px
Attempt 2 (no flicker):
a) In onAnimationStart, set the image's location to 80px
b) Move the image from -80px to 0px
Hope that made sense. Basically I flipped the way I did it
Try to use getAnimation() from your object:
public void onShowListBtnClick(View view)
{
rightPanel.startAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.slide_left));
rightPanel.getAnimation().setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animation animation) {
// write your code here
}
});
}
An easy fix is to add one line to AnimationListener.onAnimationEnd():
#Override
public void onAnimationEnd(Animation a) {
a.setAnimationListener(null);
…
}
annimation can be also stopped on screen rotation. in this case onAnimationEnd() is not being called. my workaround:
animation.setDuration(animationDuration);
animation.setAnimationListener(new AnimationListenerAdapter() {...});
view.startAnimation(animation);
handler.postDelayed(new Runnable() {
#Override
public void run() {
if(!animation.hasEnded()) {
// here you can handle this case
}
}
}, animationDuration + 100);
I had this issue because my Animation was not started in the main thread.
This resulted in a duration of 0.
However , the Animation did play correctly - it just called onAnimationEnd() immediately after execution.
If you are using repeat count as infinite, then onAnimationEnd would not get called. Check the documentation link
You can also use setUpdateListener, then check the current fraction of the animation progress and act accordingly.
Here's a Kotlin example for a fade-out animation which eventually makes the view gone from the layout:
view.animate()
.alpha(0f)
.setDuration(duration)
.setUpdateListener { animation ->
if (animation.animatedFraction > 0.99f) {
view.visibility = View.GONE
}
}
.start()
This worked for me:
#Override
public void onAnimationUpdate(ValueAnimator animation) {
if (Float.compare(animation.getAnimatedFraction(),1.0f)) {
// animation ended;
//do stuff post animation
}
}