How can I run a sequence of Animations? AnimationSet is failing me - java

I have a custom view Dial. This view has a custom animation DialAnimation that was written as a nested class of Dial. Below is the code from my Activity that instantiates Dial and attempts to perform a sequence of animations on it. When the code is run, only one of the animations is seen onscreen. What am I missing here?
Dial dial = (Dial) findViewById(R.id.dial);
DialAnimation anim1 = dial.new DialAnimation(0, 90, 3000);
DialAnimation anim2 = dial.new DialAnimation(180, 360, 3000);
anim2.setStartOffset(3500);
AnimationSet set = new AnimationSet(false);
set.addAnimation(anim1);
set.addAnimation(anim2);
dial.startAnimation(set);

one way to do it would be to set an AnimationListener on the first animation and override the onAnimationEnd() to make it start the next animation in the sequence. That would look something like this:
animation1Listener = 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) {
dial.startAnimation(animation2)
}
}
animation1.setAnimationListener(animation1Listener);
dial.startAnimation(animation1);

try animation listner in doinbackground() method this will update your animation in sequence
..OR u can use simple thread in you application .

Add a .setDuration(3500) method to each animation and ensure that the time for the duration and the time for the .setStartOffset(3500) method for the secondanimation match.

Related

How to disable button while AlphaAnimation running

I want to disable click on button when the animation running.
the code is below:
AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
anim.setDuration(4000);
anim.setRepeatMode(Animation.REVERSE);
btnTag.startAnimation(anim);
So i want to cant click the button until animation done.
I normally accomplish something like this is using an AnimationListener. It allows you to run code at various stages of the animation.
This code is untested, but the way it should look is:
AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
anim.setDuration(4000);
anim.setRepeatMode(Animation.REVERSE);
anim.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
btnTag.setClickable(false);
}
#Override
public void onAnimationEnd(Animation animation) {
btnTag.setClickable(true);
}
#Override
public void onAnimationRepeat(Animation animation) {}
});
btnTag.startAnimation(anim);
Not sure if btnTag is your button or a view holding your button, but call the button's setClickable(boolean clickable) method to enable and disable the button.
I would like to share the solution I found for this problem, for those who use data-binding:
binding.ivImage.setOnClickListener {
binding.ivImage.animate().apply {
duration=1000
scaleXBy(.5f)
scaleYBy(.5f)
rotationYBy(360f)
translationYBy(200f)
}.withEndAction {
binding.ivImage.animate().apply {
duration = 1000
scaleXBy(-.5f)
scaleYBy(-.5f)
rotationXBy(360f)
translationYBy(-200f)
}
}
}
binding.ivImage.animate().setListener(object: Animator.AnimatorListener{
override fun onAnimationStart(p0: Animator?) {
binding.ivImage.isClickable=false
binding.ivImage.isEnabled=false
}
override fun onAnimationEnd(p0: Animator?) {
binding.ivImage.isClickable=true
binding.ivImage.isEnabled=true
}
override fun onAnimationCancel(p0: Animator?) {
binding.ivImage.isClickable=true
binding.ivImage.isEnabled=true
}
override fun onAnimationRepeat(p0: Animator?) {
TODO("Not yet implemented")
}
})

How do i get the coordinates of a view during animation android

these are just the methods i can override during animationListener.
http://developer.android.com/reference/android/view/animation/Animation.AnimationListener.html
Animation animation
animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.device_box);
animation.setAnimationListener(new AnimationListener(){
#Overridepublic void onAnimationEnd(Animation arg0) {}
#Override public void onAnimationRepeat(Animation animation) {}
#Override public void onAnimationStart(Animation animation) {}});
I think adding a thread in onAnimationStart and stop it on onAnimationEnd and getting the coordinates with a loop inside the thread, this may work.
But i think that i could get some problems with buttons because, when animating them in this way, only the background moves, not button area itself
In this case, i have to investigate more with buttons
What do you think about this, is there another way to achieve what i want?
Is this the better way to do it ?
I researched, and what I got is this, not X and Y but can handle the data as get what has been animated as time.
ObjectAnimator anim = ObjectAnimator.ofFloat(box_image, "translationX", 0 , cant);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator arg0) {
double f = Math.round(arg0.getAnimatedFraction()*1000.0)/1000.0;
Log.d("datos", ""+f);
}
});
anim.setDuration(1000);
anim.start();

Android: Two ScaleAnimations performed sequentially

I want to animate a scale an ImageView vertically, wait, then perform another scale on the same ImageView. I've simplified the code below but it's essentially what I want to do:
ScaleAnimation animate = new ScaleAnimation(1,1,1,2);
animate.setDuration(1000);
animate.fillAfter(true);
ScaleAnimation animateAgain = new ScaleAnimation(1,1,2,1);
animate.setDuration(1000);
animate.fillAfter(true);
view.startAnimation(animate);
view.startAnimation(animateAgain);
I've tried multiple ways of waiting for the first animation to finish (Thread.sleep etc.) but it doesn't seem to make any difference. I assume the animation is rendered in the onDraw method or something? I'm not entirely sure how scale animations work so I can't really grasp how to solve my problem.
What's the simplest way of doing what I want to accomplish?
Thanks guys :)
There are a couple of ways:
Attach an AnimationListener to your animations.
ScaleAnimation animate = new ScaleAnimation(1,1,1,2);
animate.setDuration(1000);
animate.fillAfter(true);
animate.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationEnd(Animation animation) {
ScaleAnimation animateAgain = new ScaleAnimation(1,1,2,1);
animateAgain.setDuration(1000);
animateAgain.fillAfter(true);
view.startAnimation(animateAgain);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationStart(Animation animation) {
}});
view.startAnimation(animate);
Alternately, you can set an animation delay for your second animation.
ScaleAnimation animateAgain = new ScaleAnimation(1,1,2,1);
animateAgain.setDuration(1000);
animateAgain.fillAfter(true);
animateAgain.setStartOffset(firstAnimationDuration + delay);

How to use context inside listener?

I have code like this:
else if (v == mSettings)
{
if (disappearView.getVisibility() == View.VISIBLE)
{
AlphaAnimation fadeOutAnimation = new AlphaAnimation(1, 0); // start alpha, end alpha
fadeOutAnimation.setDuration(1000); // time for animation in milliseconds
fadeOutAnimation.setFillAfter(true); // make the transformation persist
Animation out = AnimationUtils.makeOutAnimation(this, true);
disappearView.startAnimation(out);
disappearView.setVisibility(View.INVISIBLE);
out.setAnimationListener(new Animation.AnimationListener()
{
public void onAnimationEnd(Animation animation)
{
disappearView.setVisibility(View.GONE);
Animation in = AnimationUtils.loadAnimation(this, android.R.anim.fade_in);
bannerView.startAnimation(in);
bannerView.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationRepeat(Animation animation) { }
#Override
public void onAnimationStart(Animation animation) { }
});
}
else {
Animation in = AnimationUtils.loadAnimation(this, android.R.anim.fade_in);
disappearView.startAnimation(in);
disappearView.setVisibility(View.VISIBLE);
bannerView.setVisibility(View.INVISIBLE);
bannerView.setVisibility(View.GONE);
}
}
It all works apart from this section in the animationListener:
Animation in = AnimationUtils.loadAnimation(this, android.R.anim.fade_in);
It wants a valid context but it is receiving an animationListener, what context do I give it, context really confuses me here.
Change it to:
Animation in = AnimationUtils.loadAnimation(MyActivityName.this, android.R.anim.fade_in);
It wants an instance of any class that extends Context. Since it is inside an anonymous inner class, when you use this you are referring to the inner class instance, and not to your Activity. My snippet refers to the Activity class that wraps the anonymous inner class. Since Activity extends Context, this is a valid argument.
Inside the listener, this is referring to the Listener. Try using ActivityName.this

Two animations one after another

I want to make 2 animation on activity for 2 images, and I want to do it with 2 conditions:
1. I want to start the animation after the activity finished to load to page, so instead of putting animation code under onCreate i put it under onResume is that OK? There is a better way to do it?
2. I want the second animation will start only after the first animation is finished...
Thanks
You'll want to use an Animation.AnimationListner You can set one on your first animation that will get a callback when the animation is complete. Inside that callback you can add the code that will start the second animation.
Depending on the API level you are coding for you can use AnimationSet or AnimatorSet. Also if you are extending View or one of its subclasses you can override View.onAnimationStart() and View.onAnimationFinish(). Or use the listener Tim mentions.
public class SplashActivity extends Activity{
Animation FadeInanimation, FadeOutanimation;
ImageView img;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
img= (ImageView) findViewById(R.id.img);
//Your Code Block....
FadeInanimation = AnimationUtils.loadAnimation(this,R.anim.image_fadein);
//FadeInanimation.setRepeatCount(Animation.INFINITE);
//FadeInanimation.setRepeatMode(Animation.RESTART);
FadeInanimation.setAnimationListener(FadeInAnimationListener);
FadeOutanimation = AnimationUtils.loadAnimation(this,R.anim.image_fadeout);
//FadeOutanimation.setRepeatCount(Animation.INFINITE);
//FadeOutanimation.setRepeatMode(Animation.RESTART);
FadeOutanimation.setAnimationListener(fadeOutAnimationListener);
img.startAnimation(FadeInanimation);
}
AnimationListener FadeInAnimationListener = new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
plane.startAnimation(FadeOutanimation);
}
};
}

Categories

Resources